Merge branch 'master' into atlassian-auth
Signed-off-by: Daniel Deloff <44780793+rv-ddeloff@users.noreply.github.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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}`,
|
||||
|
||||
Reference in New Issue
Block a user