Merge branch 'master' into atlassian-auth

Signed-off-by: Daniel Deloff <44780793+rv-ddeloff@users.noreply.github.com>
This commit is contained in:
Daniel Deloff
2021-10-20 22:07:38 -04:00
483 changed files with 11199 additions and 3918 deletions
+13
View File
@@ -1,5 +1,18 @@
# @backstage/plugin-auth-backend
## 0.4.4
### Patch Changes
- 0cfeea8f8f: AWS-ALB: update provider to the latest changes described [here](https://backstage.io/docs/auth/identity-resolver).
This removes the `ExperimentalIdentityResolver` type in favor of `SignInResolver` and `AuthHandler`.
The AWS ALB provider can now be configured in the same way as the Google provider in the example.
- defae8f579: Added extra configuration parameters for active directory file system identity
- Updated dependencies
- @backstage/test-utils@0.1.19
## 0.4.3
### Patch Changes
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-auth-backend",
"description": "A Backstage backend plugin that handles authentication",
"version": "0.4.3",
"version": "0.4.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -35,7 +35,7 @@
"@backstage/catalog-model": "^0.9.4",
"@backstage/config": "^0.1.10",
"@backstage/errors": "^0.1.1",
"@backstage/test-utils": "^0.1.18",
"@backstage/test-utils": "^0.1.19",
"@types/express": "^4.17.6",
"@types/passport": "^1.0.3",
"compression": "^1.7.4",
@@ -72,7 +72,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.7.15",
"@backstage/cli": "^0.7.16",
"@types/body-parser": "^1.19.0",
"@types/cookie-parser": "^1.4.2",
"@types/express-session": "^1.17.2",
@@ -22,7 +22,7 @@ import {
BackstageIdentity,
AuthProviderConfig,
} from '../../providers/types';
import { InputError, NotAllowedError } from '@backstage/errors';
import { InputError, isError, NotAllowedError } from '@backstage/errors';
import { TokenIssuer } from '../../identity/types';
import { readState, verifyNonce } from './helpers';
import { postMessageResponse, ensuresXRequestedWith } from '../flow';
@@ -153,13 +153,13 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
response,
});
} catch (error) {
const { name, message } = isError(error)
? error
: new Error('Encountered invalid error'); // Being a bit safe and not forwarding the bad value
// post error message back to popup if failure
return postMessageResponse(res, appOrigin, {
type: 'authorization_response',
error: {
name: error.name,
message: error.message,
},
error: { name, message },
});
}
}
@@ -220,7 +220,7 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
res.status(200).json(response);
} catch (error) {
res.status(401).send(`${error.message}`);
res.status(401).send(String(error));
}
}
@@ -278,5 +278,59 @@ describe('GithubAuthProvider', () => {
refreshToken: 'refresh-me',
});
});
it('should forward a new refresh token on refresh', async () => {
const mockRefreshToken = jest.spyOn(
helpers,
'executeRefreshTokenStrategy',
) as unknown as jest.MockedFunction<() => Promise<{}>>;
mockRefreshToken.mockResolvedValueOnce({
accessToken: 'a.b.c',
refreshToken: 'dont-forget-to-send-refresh',
params: {
id_token: 'my-id',
expires_in: '123',
scope: 'read_user',
},
});
const mockUserProfile = jest.spyOn(
helpers,
'executeFetchUserProfileStrategy',
) as unknown as jest.MockedFunction<() => Promise<PassportProfile>>;
mockUserProfile.mockResolvedValueOnce({
id: 'mockid',
username: 'mockuser',
provider: 'github',
displayName: 'Mocked User',
emails: [
{
value: 'mockuser@gmail.com',
},
],
});
const response = 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',
},
});
});
});
});
@@ -126,7 +126,11 @@ export class GithubAuthProvider implements OAuthHandlers {
}
async refresh(req: OAuthRefreshRequest): Promise<OAuthResponse> {
const { accessToken, params } = await executeRefreshTokenStrategy(
const {
accessToken,
refreshToken: newRefreshToken,
params,
} = await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
@@ -139,7 +143,7 @@ export class GithubAuthProvider implements OAuthHandlers {
fullProfile,
params,
accessToken,
refreshToken: req.refreshToken,
refreshToken: newRefreshToken,
});
}
@@ -150,6 +154,7 @@ 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),
@@ -275,6 +275,13 @@ export const createOktaProvider = (
const audience = envConfig.getString('audience');
const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
// This is a safe assumption as `passport-okta-oauth` uses the audience
// as the base for building the authorization, token, and user info URLs.
// https://github.com/fischerdan/passport-okta-oauth/blob/ea9ac42d/lib/passport-okta-oauth/oauth2.js#L12-L14
if (!audience.startsWith('https://')) {
throw new Error("URL for 'audience' must start with 'https://'.");
}
const catalogIdentityClient = new CatalogIdentityClient({
catalogApi,
tokenIssuer,
@@ -29,6 +29,7 @@ import {
import { AuthProviderRouteHandlers, AuthProviderFactory } from '../types';
import { postMessageResponse } from '../../lib/flow';
import { TokenIssuer } from '../../identity/types';
import { isError } from '@backstage/errors';
type SamlInfo = {
fullProfile: any;
@@ -93,12 +94,12 @@ export class SamlAuthProvider implements AuthProviderRouteHandlers {
},
});
} catch (error) {
const { name, message } = isError(error)
? error
: new Error('Encountered invalid error'); // Being a bit safe and not forwarding the bad value
return postMessageResponse(res, this.appUrl, {
type: 'authorization_response',
error: {
name: error.name,
message: error.message,
},
error: { name, message },
});
}
}
+2 -1
View File
@@ -26,7 +26,7 @@ import {
PluginDatabaseManager,
PluginEndpointDiscovery,
} from '@backstage/backend-common';
import { NotFoundError } from '@backstage/errors';
import { assertError, NotFoundError } from '@backstage/errors';
import { CatalogClient } from '@backstage/catalog-client';
import { Config } from '@backstage/config';
import { createOidcRouter, DatabaseKeyStore, TokenFactory } from '../identity';
@@ -121,6 +121,7 @@ export async function createRouter({
router.use(`/${providerId}`, r);
} catch (e) {
assertError(e);
if (process.env.NODE_ENV !== 'development') {
throw new Error(
`Failed to initialize ${providerId} auth provider, ${e.message}`,