auth-backend: remove disableRefresh option
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-auth-backend': patch
|
||||
---
|
||||
|
||||
The Auth0 adapter no longer disables session refreshing.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-auth-backend': minor
|
||||
---
|
||||
|
||||
Removed the explicit `disableRefresh` option from `OAuthAdapter`. Refresh can still be disabled for a provider by not implementing the `refresh` method.
|
||||
@@ -153,7 +153,6 @@ export const createOktaProvider: AuthProviderFactory = ({
|
||||
|
||||
// Wrap the OAuthProviderHandlers with OAuthProvider, which implements AuthProviderRouteHandlers
|
||||
return OAuthProvider.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
tokenIssuer,
|
||||
});
|
||||
|
||||
@@ -586,11 +586,7 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
|
||||
handlers: OAuthHandlers,
|
||||
options: Pick<
|
||||
Options,
|
||||
| 'providerId'
|
||||
| 'persistScopes'
|
||||
| 'disableRefresh'
|
||||
| 'tokenIssuer'
|
||||
| 'callbackUrl'
|
||||
'providerId' | 'persistScopes' | 'tokenIssuer' | 'callbackUrl'
|
||||
>,
|
||||
): OAuthAdapter;
|
||||
// (undocumented)
|
||||
|
||||
@@ -60,7 +60,6 @@ describe('OAuthAdapter', () => {
|
||||
const oAuthProviderOptions = {
|
||||
providerId: 'test-provider',
|
||||
secure: false,
|
||||
disableRefresh: true,
|
||||
appOrigin: 'http://localhost:3000',
|
||||
cookieDomain: 'example.com',
|
||||
cookiePath: '/auth/test-provider',
|
||||
@@ -110,7 +109,6 @@ describe('OAuthAdapter', () => {
|
||||
it('sets the refresh cookie if refresh is enabled', async () => {
|
||||
const oauthProvider = new OAuthAdapter(providerInstance, {
|
||||
...oAuthProviderOptions,
|
||||
disableRefresh: false,
|
||||
isOriginAllowed: () => false,
|
||||
});
|
||||
|
||||
@@ -153,7 +151,6 @@ describe('OAuthAdapter', () => {
|
||||
};
|
||||
const oauthProvider = new OAuthAdapter(handlers, {
|
||||
...oAuthProviderOptions,
|
||||
disableRefresh: false,
|
||||
persistScopes: true,
|
||||
});
|
||||
|
||||
@@ -238,36 +235,9 @@ describe('OAuthAdapter', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('does not set the refresh cookie if refresh is disabled', async () => {
|
||||
const oauthProvider = new OAuthAdapter(providerInstance, {
|
||||
...oAuthProviderOptions,
|
||||
disableRefresh: true,
|
||||
isOriginAllowed: () => false,
|
||||
});
|
||||
|
||||
const mockRequest = {
|
||||
cookies: {
|
||||
'test-provider-nonce': 'nonce',
|
||||
},
|
||||
query: {
|
||||
state: 'nonce',
|
||||
},
|
||||
} as unknown as express.Request;
|
||||
|
||||
const mockResponse = {
|
||||
cookie: jest.fn().mockReturnThis(),
|
||||
setHeader: jest.fn().mockReturnThis(),
|
||||
end: jest.fn().mockReturnThis(),
|
||||
} as unknown as express.Response;
|
||||
|
||||
await oauthProvider.frameHandler(mockRequest, mockResponse);
|
||||
expect(mockResponse.cookie).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('removes refresh cookie when logging out', async () => {
|
||||
const oauthProvider = new OAuthAdapter(providerInstance, {
|
||||
...oAuthProviderOptions,
|
||||
disableRefresh: false,
|
||||
isOriginAllowed: () => false,
|
||||
});
|
||||
|
||||
@@ -292,10 +262,8 @@ describe('OAuthAdapter', () => {
|
||||
});
|
||||
|
||||
it('gets new access-token when refreshing', async () => {
|
||||
oAuthProviderOptions.disableRefresh = false;
|
||||
const oauthProvider = new OAuthAdapter(providerInstance, {
|
||||
...oAuthProviderOptions,
|
||||
disableRefresh: false,
|
||||
isOriginAllowed: () => false,
|
||||
});
|
||||
|
||||
@@ -327,26 +295,6 @@ describe('OAuthAdapter', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('handles refresh without capabilities', async () => {
|
||||
const oauthProvider = new OAuthAdapter(providerInstance, {
|
||||
...oAuthProviderOptions,
|
||||
disableRefresh: true,
|
||||
isOriginAllowed: () => false,
|
||||
});
|
||||
|
||||
const mockRequest = {
|
||||
header: () => 'XMLHttpRequest',
|
||||
} as unknown as express.Request;
|
||||
|
||||
const mockResponse = {} as unknown as express.Response;
|
||||
|
||||
await expect(
|
||||
oauthProvider.refresh(mockRequest, mockResponse),
|
||||
).rejects.toThrow(
|
||||
'Refresh token is not supported for provider test-provider',
|
||||
);
|
||||
});
|
||||
|
||||
it('sets the correct cookie configuration using a callbackUrl', async () => {
|
||||
const config = {
|
||||
baseUrl: 'http://domain.org/auth',
|
||||
|
||||
@@ -48,7 +48,6 @@ export const TEN_MINUTES_MS = 600 * 1000;
|
||||
export type Options = {
|
||||
providerId: string;
|
||||
secure: boolean;
|
||||
disableRefresh?: boolean;
|
||||
persistScopes?: boolean;
|
||||
cookieDomain: string;
|
||||
cookiePath: string;
|
||||
@@ -64,11 +63,7 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
|
||||
handlers: OAuthHandlers,
|
||||
options: Pick<
|
||||
Options,
|
||||
| 'providerId'
|
||||
| 'persistScopes'
|
||||
| 'disableRefresh'
|
||||
| 'tokenIssuer'
|
||||
| 'callbackUrl'
|
||||
'providerId' | 'persistScopes' | 'tokenIssuer' | 'callbackUrl'
|
||||
>,
|
||||
): OAuthAdapter {
|
||||
const { origin: appOrigin } = new URL(config.appUrl);
|
||||
@@ -170,7 +165,7 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
|
||||
response.providerInfo.scope = state.scope;
|
||||
}
|
||||
|
||||
if (refreshToken && !this.options.disableRefresh) {
|
||||
if (refreshToken) {
|
||||
// set new refresh token
|
||||
this.setRefreshTokenCookie(res, refreshToken);
|
||||
}
|
||||
@@ -210,7 +205,7 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
|
||||
throw new AuthenticationError('Invalid X-Requested-With header');
|
||||
}
|
||||
|
||||
if (!this.handlers.refresh || this.options.disableRefresh) {
|
||||
if (!this.handlers.refresh) {
|
||||
throw new InputError(
|
||||
`Refresh token is not supported for provider ${this.options.providerId}`,
|
||||
);
|
||||
|
||||
@@ -243,7 +243,6 @@ export const auth0 = createAuthProviderIntegration({
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: true,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
|
||||
@@ -261,7 +261,6 @@ export const bitbucket = createAuthProviderIntegration({
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
|
||||
@@ -248,7 +248,6 @@ export const gitlab = createAuthProviderIntegration({
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
|
||||
@@ -238,7 +238,6 @@ export const google = createAuthProviderIntegration({
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
|
||||
@@ -267,7 +267,6 @@ export const microsoft = createAuthProviderIntegration({
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
|
||||
@@ -43,6 +43,7 @@ import {
|
||||
SignInResolver,
|
||||
} from '../types';
|
||||
import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
|
||||
import { InputError } from '@backstage/errors';
|
||||
|
||||
type PrivateInfo = {
|
||||
refreshToken: string;
|
||||
@@ -56,6 +57,7 @@ export type OAuth2AuthProviderOptions = OAuthProviderOptions & {
|
||||
scope?: string;
|
||||
resolverContext: AuthResolverContext;
|
||||
includeBasicAuth?: boolean;
|
||||
disableRefresh?: boolean;
|
||||
};
|
||||
|
||||
export class OAuth2AuthProvider implements OAuthHandlers {
|
||||
@@ -63,11 +65,13 @@ export class OAuth2AuthProvider implements OAuthHandlers {
|
||||
private readonly signInResolver?: SignInResolver<OAuthResult>;
|
||||
private readonly authHandler: AuthHandler<OAuthResult>;
|
||||
private readonly resolverContext: AuthResolverContext;
|
||||
private readonly disableRefresh: boolean;
|
||||
|
||||
constructor(options: OAuth2AuthProviderOptions) {
|
||||
this.signInResolver = options.signInResolver;
|
||||
this.authHandler = options.authHandler;
|
||||
this.resolverContext = options.resolverContext;
|
||||
this.disableRefresh = options.disableRefresh ?? false;
|
||||
|
||||
this._strategy = new OAuth2Strategy(
|
||||
{
|
||||
@@ -132,6 +136,9 @@ export class OAuth2AuthProvider implements OAuthHandlers {
|
||||
}
|
||||
|
||||
async refresh(req: OAuthRefreshRequest) {
|
||||
if (this.disableRefresh) {
|
||||
throw new InputError('Session refreshes have been disabled');
|
||||
}
|
||||
const refreshTokenResponse = await executeRefreshTokenStrategy(
|
||||
this._strategy,
|
||||
req.refreshToken,
|
||||
@@ -243,10 +250,10 @@ export const oauth2 = createAuthProviderIntegration({
|
||||
scope,
|
||||
includeBasicAuth,
|
||||
resolverContext,
|
||||
disableRefresh,
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
|
||||
@@ -262,7 +262,6 @@ export const oidc = createAuthProviderIntegration({
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
|
||||
@@ -271,7 +271,6 @@ export const okta = createAuthProviderIntegration({
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
|
||||
@@ -238,7 +238,6 @@ export const onelogin = createAuthProviderIntegration({
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user