auth-backend: always exchange and never return refresh tokens to clients

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2021-12-28 17:30:00 +01:00
parent 2f26120a36
commit c88cdacc1a
19 changed files with 296 additions and 262 deletions
+29
View File
@@ -0,0 +1,29 @@
---
'@backstage/plugin-auth-backend': minor
---
Avoid ever returning OAuth refresh tokens back to the client, and always exchange refresh tokens for a new one when available for all providers.
This comes with a breaking change to the TypeScript API for custom auth providers. The `refresh` method of `OAuthHandlers` implementation must now return a `{ response, refreshToken }` object rather than a direct response. Existing `refresh` implementations are typically migrated by changing an existing return expression that looks like this:
```ts
return await this.handleResult({
fullProfile,
params,
accessToken,
refreshToken,
});
```
Into the following:
```ts
return {
response: await this.handleResult({
fullProfile,
params,
accessToken,
}),
refreshToken,
};
```
+15 -10
View File
@@ -27,10 +27,13 @@ export class AtlassianAuthProvider implements OAuthHandlers {
// (undocumented)
handler(req: express.Request): Promise<{
response: OAuthResponse;
refreshToken: string;
refreshToken: string | undefined;
}>;
// (undocumented)
refresh(req: OAuthRefreshRequest): Promise<OAuthResponse>;
refresh(req: OAuthRefreshRequest): Promise<{
response: OAuthResponse;
refreshToken: string | undefined;
}>;
// Warning: (ae-forgotten-export) The symbol "RedirectInfo" needs to be exported by the entry point index.d.ts
//
// (undocumented)
@@ -488,7 +491,10 @@ export interface OAuthHandlers {
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
refresh?(req: OAuthRefreshRequest): Promise<OAuthResponse>;
refresh?(req: OAuthRefreshRequest): Promise<{
response: OAuthResponse;
refreshToken?: string;
}>;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
@@ -503,7 +509,6 @@ export type OAuthProviderInfo = {
idToken?: string;
expiresInSeconds?: number;
scope: string;
refreshToken?: string;
};
// Warning: (ae-missing-release-tag) "OAuthProviderOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
@@ -703,11 +708,11 @@ export type WebMessageResponse =
//
// src/identity/types.d.ts:31:9 - (ae-forgotten-export) The symbol "AnyJWK" needs to be exported by the entry point index.d.ts
// src/providers/aws-alb/provider.d.ts:77:5 - (ae-forgotten-export) The symbol "AwsAlbResult" needs to be exported by the entry point index.d.ts
// src/providers/github/provider.d.ts:71:58 - (tsdoc-escape-greater-than) The ">" character should be escaped using a backslash to avoid confusion with an HTML tag
// src/providers/github/provider.d.ts:71:90 - (tsdoc-escape-greater-than) The ">" character should be escaped using a backslash to avoid confusion with an HTML tag
// src/providers/github/provider.d.ts:71:89 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// src/providers/github/provider.d.ts:71:67 - (tsdoc-malformed-html-name) Invalid HTML element: Expecting an HTML name
// src/providers/github/provider.d.ts:71:68 - (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// src/providers/github/provider.d.ts:78:5 - (ae-forgotten-export) The symbol "StateEncoder" needs to be exported by the entry point index.d.ts
// src/providers/github/provider.d.ts:74:58 - (tsdoc-escape-greater-than) The ">" character should be escaped using a backslash to avoid confusion with an HTML tag
// src/providers/github/provider.d.ts:74:90 - (tsdoc-escape-greater-than) The ">" character should be escaped using a backslash to avoid confusion with an HTML tag
// src/providers/github/provider.d.ts:74:89 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// src/providers/github/provider.d.ts:74:67 - (tsdoc-malformed-html-name) Invalid HTML element: Expecting an HTML name
// src/providers/github/provider.d.ts:74:68 - (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// src/providers/github/provider.d.ts:81:5 - (ae-forgotten-export) The symbol "StateEncoder" needs to be exported by the entry point index.d.ts
// src/providers/types.d.ts:100:5 - (ae-forgotten-export) The symbol "AuthProviderConfig" needs to be exported by the entry point index.d.ts
```
@@ -57,7 +57,10 @@ describe('OAuthAdapter', () => {
};
}
async refresh() {
return mockResponseData;
return {
response: mockResponseData,
refreshToken: 'token',
};
}
}
const providerInstance = new MyAuthProvider();
@@ -257,7 +260,10 @@ describe('OAuthAdapter', () => {
});
it('correctly populates incomplete identities', async () => {
const mockRefresh = jest.fn<Promise<OAuthResponse>, [express.Request]>();
const mockRefresh = jest.fn<
Promise<{ response: OAuthResponse }>,
[express.Request]
>();
const oauthProvider = new OAuthAdapter(
{
@@ -291,10 +297,12 @@ describe('OAuthAdapter', () => {
// Without a token
mockRefresh.mockResolvedValueOnce({
...mockResponseData,
backstageIdentity: {
id: 'foo',
token: '',
response: {
...mockResponseData,
backstageIdentity: {
id: 'foo',
token: '',
},
},
});
await oauthProvider.refresh(mockRequest, mockResponse);
@@ -315,10 +323,12 @@ describe('OAuthAdapter', () => {
// With a token
mockRefresh.mockResolvedValueOnce({
...mockResponseData,
backstageIdentity: {
id: 'foo',
token: `z.${mkTokenBody({ sub: 'user:my-ns/foo' })}.z`,
response: {
...mockResponseData,
backstageIdentity: {
id: 'foo',
token: `z.${mkTokenBody({ sub: 'user:my-ns/foo' })}.z`,
},
},
});
await oauthProvider.refresh(mockRequest, mockResponse);
@@ -212,19 +212,15 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
const forwardReq = Object.assign(req, { scope, refreshToken });
// get new access_token
const response = await this.handlers.refresh(
forwardReq as OAuthRefreshRequest,
);
const { response, refreshToken: newRefreshToken } =
await this.handlers.refresh(forwardReq as OAuthRefreshRequest);
const backstageIdentity = await this.populateIdentity(
response.backstageIdentity,
);
if (
response.providerInfo.refreshToken &&
response.providerInfo.refreshToken !== refreshToken
) {
this.setRefreshTokenCookie(res, response.providerInfo.refreshToken);
if (newRefreshToken && newRefreshToken !== refreshToken) {
this.setRefreshTokenCookie(res, newRefreshToken);
}
res.status(200).json({ ...response, backstageIdentity });
+4 -5
View File
@@ -79,10 +79,6 @@ export type OAuthProviderInfo = {
* Scopes granted for the access token.
*/
scope: string;
/**
* A refresh token issued for the signed in user
*/
refreshToken?: string;
};
export type OAuthState = {
@@ -130,7 +126,10 @@ export interface OAuthHandlers {
* @param {string} refreshToken
* @param {string} scope
*/
refresh?(req: OAuthRefreshRequest): Promise<OAuthResponse>;
refresh?(req: OAuthRefreshRequest): Promise<{
response: OAuthResponse;
refreshToken?: string;
}>;
/**
* (Optional) Sign out of the auth provider.
@@ -78,20 +78,22 @@ describe('createAtlassianProvider', () => {
refreshToken: 'wacka',
},
});
const { response } = await provider.handler({} as any);
expect(response).toEqual({
providerInfo: {
accessToken: 'accessToken',
expiresInSeconds: 123,
idToken: 'idToken',
scope: 'scope',
refreshToken: 'wacka',
},
profile: {
email: 'conrad@example.com',
displayName: 'Conrad',
picture: 'http://google.com/lols',
const result = await provider.handler({} as any);
expect(result).toEqual({
response: {
providerInfo: {
accessToken: 'accessToken',
expiresInSeconds: 123,
idToken: 'idToken',
scope: 'scope',
},
profile: {
email: 'conrad@example.com',
displayName: 'Conrad',
picture: 'http://google.com/lols',
},
},
refreshToken: 'wacka',
});
});
@@ -127,20 +129,22 @@ describe('createAtlassianProvider', () => {
],
});
const response = await provider.refresh({} as any);
const result = await provider.refresh({} as any);
expect(response).toEqual({
profile: {
displayName: 'Mocked User',
email: 'mockuser@gmail.com',
picture: 'http://google.com/lols',
},
providerInfo: {
accessToken: 'a.b.c',
idToken: 'my-id',
refreshToken: 'dont-forget-to-send-refresh',
scope: 'read_user',
expect(result).toEqual({
response: {
profile: {
displayName: 'Mocked User',
email: 'mockuser@gmail.com',
picture: 'http://google.com/lols',
},
providerInfo: {
accessToken: 'a.b.c',
idToken: 'my-id',
scope: 'read_user',
},
},
refreshToken: 'dont-forget-to-send-refresh',
});
});
});
@@ -107,9 +107,7 @@ export class AtlassianAuthProvider implements OAuthHandlers {
});
}
async handler(
req: express.Request,
): Promise<{ response: OAuthResponse; refreshToken: string }> {
async handler(req: express.Request) {
const { result } = await executeFrameHandlerStrategy<OAuthResult>(
req,
this._strategy,
@@ -117,7 +115,7 @@ export class AtlassianAuthProvider implements OAuthHandlers {
return {
response: await this.handleResult(result),
refreshToken: result.refreshToken ?? '',
refreshToken: result.refreshToken,
};
}
@@ -128,7 +126,6 @@ export class AtlassianAuthProvider implements OAuthHandlers {
providerInfo: {
idToken: result.params.id_token,
accessToken: result.accessToken,
refreshToken: result.refreshToken,
scope: result.params.scope,
expiresInSeconds: result.params.expires_in,
},
@@ -152,28 +149,27 @@ export class AtlassianAuthProvider implements OAuthHandlers {
return response;
}
async refresh(req: OAuthRefreshRequest): Promise<OAuthResponse> {
const {
accessToken,
params,
refreshToken: newRefreshToken,
} = await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
async refresh(req: OAuthRefreshRequest) {
const { accessToken, params, refreshToken } =
await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
const fullProfile = await executeFetchUserProfileStrategy(
this._strategy,
accessToken,
);
return this.handleResult({
fullProfile,
params,
accessToken,
refreshToken: newRefreshToken,
});
return {
response: await this.handleResult({
fullProfile,
params,
accessToken,
}),
refreshToken,
};
}
}
@@ -113,9 +113,7 @@ export class Auth0AuthProvider implements OAuthHandlers {
});
}
async handler(
req: express.Request,
): Promise<{ response: OAuthResponse; refreshToken: string }> {
async handler(req: express.Request) {
const { result, privateInfo } = await executeFrameHandlerStrategy<
OAuthResult,
PrivateInfo
@@ -127,24 +125,27 @@ export class Auth0AuthProvider implements OAuthHandlers {
};
}
async refresh(req: OAuthRefreshRequest): Promise<OAuthResponse> {
const { accessToken, params } = await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
async refresh(req: OAuthRefreshRequest) {
const { accessToken, refreshToken, params } =
await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
const fullProfile = await executeFetchUserProfileStrategy(
this._strategy,
accessToken,
);
return this.handleResult({
fullProfile,
params,
accessToken,
refreshToken: req.refreshToken,
});
return {
response: await this.handleResult({
fullProfile,
params,
accessToken,
}),
refreshToken,
};
}
private async handleResult(result: OAuthResult) {
@@ -138,9 +138,7 @@ export class BitbucketAuthProvider implements OAuthHandlers {
});
}
async handler(
req: express.Request,
): Promise<{ response: OAuthResponse; refreshToken: string }> {
async handler(req: express.Request) {
const { result, privateInfo } = await executeFrameHandlerStrategy<
OAuthResult,
PrivateInfo
@@ -152,22 +150,25 @@ export class BitbucketAuthProvider implements OAuthHandlers {
};
}
async refresh(req: OAuthRefreshRequest): Promise<OAuthResponse> {
const { accessToken, params } = await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
async refresh(req: OAuthRefreshRequest) {
const { accessToken, refreshToken, params } =
await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
const fullProfile = await executeFetchUserProfileStrategy(
this._strategy,
accessToken,
);
return this.handleResult({
fullProfile,
params,
accessToken,
refreshToken: req.refreshToken,
});
return {
response: await this.handleResult({
fullProfile,
params,
accessToken,
}),
refreshToken,
};
}
private async handleResult(result: BitbucketOAuthResult) {
@@ -316,24 +316,26 @@ describe('GithubAuthProvider', () => {
],
});
const response = await provider.refresh({} as any);
const result = await provider.refresh({} as any);
expect(response).toEqual({
backstageIdentity: {
id: 'mockuser',
token: 'token-for-mockuser',
},
profile: {
displayName: 'Mocked User',
email: 'mockuser@gmail.com',
picture: undefined,
},
providerInfo: {
accessToken: 'a.b.c',
refreshToken: 'dont-forget-to-send-refresh',
expiresInSeconds: 123,
scope: 'read_user',
expect(result).toEqual({
response: {
backstageIdentity: {
id: 'mockuser',
token: 'token-for-mockuser',
},
profile: {
displayName: 'Mocked User',
email: 'mockuser@gmail.com',
picture: undefined,
},
providerInfo: {
accessToken: 'a.b.c',
expiresInSeconds: 123,
scope: 'read_user',
},
},
refreshToken: 'dont-forget-to-send-refresh',
});
});
});
@@ -129,26 +129,26 @@ export class GithubAuthProvider implements OAuthHandlers {
};
}
async refresh(req: OAuthRefreshRequest): Promise<OAuthResponse> {
const {
accessToken,
refreshToken: newRefreshToken,
params,
} = await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
async refresh(req: OAuthRefreshRequest) {
const { accessToken, refreshToken, params } =
await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
const fullProfile = await executeFetchUserProfileStrategy(
this._strategy,
accessToken,
);
return this.handleResult({
fullProfile,
params,
accessToken,
refreshToken: newRefreshToken,
});
return {
response: await this.handleResult({
fullProfile,
params,
accessToken,
}),
refreshToken,
};
}
private async handleResult(result: GithubOAuthResult) {
@@ -158,7 +158,6 @@ export class GithubAuthProvider implements OAuthHandlers {
const response: OAuthResponse = {
providerInfo: {
accessToken: result.accessToken,
refreshToken: result.refreshToken, // GitHub expires the old refresh token when used
scope: result.params.scope,
expiresInSeconds:
expiresInStr === undefined ? undefined : Number(expiresInStr),
@@ -184,23 +184,25 @@ describe('GitlabAuthProvider', () => {
],
});
const response = await provider.refresh({} as any);
const result = await provider.refresh({} as any);
expect(response).toEqual({
backstageIdentity: {
id: 'mockuser',
},
profile: {
displayName: 'Mocked User',
email: 'mockuser@gmail.com',
picture: 'http://gitlab.com/lols',
},
providerInfo: {
accessToken: 'a.b.c',
idToken: 'my-id',
refreshToken: 'dont-forget-to-send-refresh',
scope: 'read_user',
expect(result).toEqual({
response: {
backstageIdentity: {
id: 'mockuser',
},
profile: {
displayName: 'Mocked User',
email: 'mockuser@gmail.com',
picture: 'http://gitlab.com/lols',
},
providerInfo: {
accessToken: 'a.b.c',
idToken: 'my-id',
scope: 'read_user',
},
},
refreshToken: 'dont-forget-to-send-refresh',
});
});
});
@@ -132,9 +132,7 @@ export class GitlabAuthProvider implements OAuthHandlers {
});
}
async handler(
req: express.Request,
): Promise<{ response: OAuthResponse; refreshToken: string }> {
async handler(req: express.Request) {
const { result, privateInfo } = await executeFrameHandlerStrategy<
OAuthResult,
PrivateInfo
@@ -146,28 +144,26 @@ export class GitlabAuthProvider implements OAuthHandlers {
};
}
async refresh(req: OAuthRefreshRequest): Promise<OAuthResponse> {
const {
accessToken,
refreshToken: newRefreshToken,
params,
} = await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
async refresh(req: OAuthRefreshRequest) {
const { accessToken, refreshToken, params } =
await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
const fullProfile = await executeFetchUserProfileStrategy(
this._strategy,
accessToken,
);
return this.handleResult({
fullProfile,
params,
accessToken,
refreshToken: newRefreshToken,
});
return {
response: await this.handleResult({
fullProfile,
params,
accessToken,
}),
refreshToken,
};
}
private async handleResult(result: OAuthResult): Promise<OAuthResponse> {
@@ -177,7 +173,6 @@ export class GitlabAuthProvider implements OAuthHandlers {
providerInfo: {
idToken: result.params.id_token,
accessToken: result.accessToken,
refreshToken: result.refreshToken, // GitLab expires the old refresh token when used
scope: result.params.scope,
expiresInSeconds: result.params.expires_in,
},
@@ -113,9 +113,7 @@ export class GoogleAuthProvider implements OAuthHandlers {
});
}
async handler(
req: express.Request,
): Promise<{ response: OAuthResponse; refreshToken: string }> {
async handler(req: express.Request) {
const { result, privateInfo } = await executeFrameHandlerStrategy<
OAuthResult,
PrivateInfo
@@ -127,22 +125,26 @@ export class GoogleAuthProvider implements OAuthHandlers {
};
}
async refresh(req: OAuthRefreshRequest): Promise<OAuthResponse> {
const { accessToken, params } = await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
async refresh(req: OAuthRefreshRequest) {
const { accessToken, refreshToken, params } =
await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
const fullProfile = await executeFetchUserProfileStrategy(
this._strategy,
accessToken,
);
return this.handleResult({
fullProfile,
params,
accessToken,
refreshToken: req.refreshToken,
});
return {
response: await this.handleResult({
fullProfile,
params,
accessToken,
}),
refreshToken,
};
}
private async handleResult(result: OAuthResult) {
@@ -104,9 +104,7 @@ export class MicrosoftAuthProvider implements OAuthHandlers {
});
}
async handler(
req: express.Request,
): Promise<{ response: OAuthResponse; refreshToken: string }> {
async handler(req: express.Request) {
const { result, privateInfo } = await executeFrameHandlerStrategy<
OAuthResult,
PrivateInfo
@@ -118,24 +116,27 @@ export class MicrosoftAuthProvider implements OAuthHandlers {
};
}
async refresh(req: OAuthRefreshRequest): Promise<OAuthResponse> {
const { accessToken, params } = await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
async refresh(req: OAuthRefreshRequest) {
const { accessToken, refreshToken, params } =
await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
const fullProfile = await executeFetchUserProfileStrategy(
this._strategy,
accessToken,
);
return this.handleResult({
fullProfile,
params,
accessToken,
refreshToken: req.refreshToken,
});
return {
response: await this.handleResult({
fullProfile,
params,
accessToken,
}),
refreshToken,
};
}
private async handleResult(result: OAuthResult) {
@@ -127,9 +127,7 @@ export class OAuth2AuthProvider implements OAuthHandlers {
});
}
async handler(
req: express.Request,
): Promise<{ response: OAuthResponse; refreshToken: string }> {
async handler(req: express.Request) {
const { result, privateInfo } = await executeFrameHandlerStrategy<
OAuthResult,
PrivateInfo
@@ -141,29 +139,27 @@ export class OAuth2AuthProvider implements OAuthHandlers {
};
}
async refresh(req: OAuthRefreshRequest): Promise<OAuthResponse> {
async refresh(req: OAuthRefreshRequest) {
const refreshTokenResponse = await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
const {
accessToken,
params,
refreshToken: updatedRefreshToken,
} = refreshTokenResponse;
const { accessToken, params, refreshToken } = refreshTokenResponse;
const fullProfile = await executeFetchUserProfileStrategy(
this._strategy,
accessToken,
);
return this.handleResult({
fullProfile,
params,
accessToken,
refreshToken: updatedRefreshToken,
});
return {
response: await this.handleResult({
fullProfile,
params,
accessToken,
}),
refreshToken,
};
}
private async handleResult(result: OAuthResult) {
@@ -175,7 +171,6 @@ export class OAuth2AuthProvider implements OAuthHandlers {
accessToken: result.accessToken,
scope: result.params.scope,
expiresInSeconds: result.params.expires_in,
refreshToken: result.refreshToken,
},
profile,
};
@@ -112,34 +112,31 @@ export class OidcAuthProvider implements OAuthHandlers {
return await executeRedirectStrategy(req, strategy, options);
}
async handler(
req: express.Request,
): Promise<{ response: OAuthResponse; refreshToken?: string }> {
async handler(req: express.Request) {
const { strategy } = await this.implementation;
const strategyResponse = await executeFrameHandlerStrategy<
const { result, privateInfo } = await executeFrameHandlerStrategy<
OidcAuthResult,
PrivateInfo
>(req, strategy);
const {
result: { userinfo, tokenset },
privateInfo,
} = strategyResponse;
const identityResponse = await this.handleResult({ tokenset, userinfo });
return {
response: identityResponse,
response: await this.handleResult(result),
refreshToken: privateInfo.refreshToken,
};
}
async refresh(req: OAuthRefreshRequest): Promise<OAuthResponse> {
async refresh(req: OAuthRefreshRequest) {
const { client } = await this.implementation;
const tokenset = await client.refresh(req.refreshToken);
if (!tokenset.access_token) {
throw new Error('Refresh failed');
}
const profile = await client.userinfo(tokenset.access_token);
return this.handleResult({ tokenset, userinfo: profile });
const userinfo = await client.userinfo(tokenset.access_token);
return {
response: await this.handleResult({ tokenset, userinfo }),
refreshToken: tokenset.refresh_token,
};
}
private async setupStrategy(options: Options): Promise<OidcImpl> {
@@ -190,7 +187,6 @@ export class OidcAuthProvider implements OAuthHandlers {
providerInfo: {
idToken: result.tokenset.id_token,
accessToken: result.tokenset.access_token!,
refreshToken: result.tokenset.refresh_token,
scope: result.tokenset.scope!,
expiresInSeconds: result.tokenset.expires_in,
},
@@ -133,9 +133,7 @@ export class OktaAuthProvider implements OAuthHandlers {
});
}
async handler(
req: express.Request,
): Promise<{ response: OAuthResponse; refreshToken: string }> {
async handler(req: express.Request) {
const { result, privateInfo } = await executeFrameHandlerStrategy<
OAuthResult,
PrivateInfo
@@ -147,7 +145,7 @@ export class OktaAuthProvider implements OAuthHandlers {
};
}
async refresh(req: OAuthRefreshRequest): Promise<OAuthResponse> {
async refresh(req: OAuthRefreshRequest) {
const { accessToken, refreshToken, params } =
await executeRefreshTokenStrategy(
this._strategy,
@@ -160,12 +158,14 @@ export class OktaAuthProvider implements OAuthHandlers {
accessToken,
);
return this.handleResult({
fullProfile,
params,
accessToken,
return {
response: await this.handleResult({
fullProfile,
params,
accessToken,
}),
refreshToken,
});
};
}
private async handleResult(result: OAuthResult) {
@@ -177,7 +177,6 @@ export class OktaAuthProvider implements OAuthHandlers {
accessToken: result.accessToken,
scope: result.params.scope,
expiresInSeconds: result.params.expires_in,
refreshToken: result.refreshToken,
},
profile,
};
@@ -112,9 +112,7 @@ export class OneLoginProvider implements OAuthHandlers {
});
}
async handler(
req: express.Request,
): Promise<{ response: OAuthResponse; refreshToken: string }> {
async handler(req: express.Request) {
const { result, privateInfo } = await executeFrameHandlerStrategy<
OAuthResult,
PrivateInfo
@@ -126,23 +124,27 @@ export class OneLoginProvider implements OAuthHandlers {
};
}
async refresh(req: OAuthRefreshRequest): Promise<OAuthResponse> {
const { accessToken, params } = await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
async refresh(req: OAuthRefreshRequest) {
const { accessToken, refreshToken, params } =
await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
);
const fullProfile = await executeFetchUserProfileStrategy(
this._strategy,
accessToken,
);
return this.handleResult({
fullProfile,
params,
accessToken,
});
return {
response: await this.handleResult({
fullProfile,
params,
accessToken,
}),
refreshToken,
};
}
private async handleResult(result: OAuthResult) {