packages/core: rename AuthHelper to AuthConnector
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import GoogleIcon from '@material-ui/icons/AcUnit';
|
||||
import { AuthHelper } from '../../lib/AuthHelper';
|
||||
import { DefaultAuthConnector } from '../../lib/AuthConnector';
|
||||
import { GoogleSession } from './types';
|
||||
import {
|
||||
OAuthApi,
|
||||
@@ -37,7 +37,7 @@ const SCOPE_PREFIX = 'https://www.googleapis.com/auth/';
|
||||
|
||||
class GoogleAuth implements OAuthApi, OpenIdConnectApi {
|
||||
static create(oauthRequestApi: OAuthRequestApi) {
|
||||
const helper = new AuthHelper({
|
||||
const connector = new DefaultAuthConnector({
|
||||
providerPath: 'google/',
|
||||
environment: 'dev',
|
||||
provider: {
|
||||
@@ -56,7 +56,7 @@ class GoogleAuth implements OAuthApi, OpenIdConnectApi {
|
||||
});
|
||||
|
||||
const sessionManager = new RefreshingAuthSessionManager({
|
||||
helper,
|
||||
connector,
|
||||
defaultScopes: new Set([
|
||||
'openid',
|
||||
`${SCOPE_PREFIX}userinfo.email`,
|
||||
|
||||
+7
-7
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import ProviderIcon from '@material-ui/icons/AcUnit';
|
||||
import { AuthHelper } from './AuthHelper';
|
||||
import { DefaultAuthConnector } from './DefaultAuthConnector';
|
||||
import MockOAuthApi from '../../OAuthRequestManager/MockOAuthApi';
|
||||
import * as loginPopup from '../loginPopup';
|
||||
|
||||
@@ -37,7 +37,7 @@ const defaultOptions = {
|
||||
}),
|
||||
};
|
||||
|
||||
describe('AuthHelper', () => {
|
||||
describe('DefaultAuthConnector', () => {
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
anyFetch.resetMocks();
|
||||
@@ -53,7 +53,7 @@ describe('AuthHelper', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
const helper = new AuthHelper<any>(defaultOptions);
|
||||
const helper = new DefaultAuthConnector<any>(defaultOptions);
|
||||
const session = await helper.refreshSession();
|
||||
expect(session.idToken).toBe('mock-id-token');
|
||||
expect(session.accessToken).toBe('mock-access-token');
|
||||
@@ -65,7 +65,7 @@ describe('AuthHelper', () => {
|
||||
it('should handle failure to refresh session', async () => {
|
||||
anyFetch.mockRejectOnce(new Error('Network NOPE'));
|
||||
|
||||
const helper = new AuthHelper(defaultOptions);
|
||||
const helper = new DefaultAuthConnector(defaultOptions);
|
||||
await expect(helper.refreshSession()).rejects.toThrow(
|
||||
'Auth refresh request failed, Error: Network NOPE',
|
||||
);
|
||||
@@ -74,7 +74,7 @@ describe('AuthHelper', () => {
|
||||
it('should handle failure response when refreshing session', async () => {
|
||||
anyFetch.mockResponseOnce({}, { status: 401, statusText: 'NOPE' });
|
||||
|
||||
const helper = new AuthHelper(defaultOptions);
|
||||
const helper = new DefaultAuthConnector(defaultOptions);
|
||||
await expect(helper.refreshSession()).rejects.toThrow(
|
||||
'Auth refresh request failed with status NOPE',
|
||||
);
|
||||
@@ -82,7 +82,7 @@ describe('AuthHelper', () => {
|
||||
|
||||
it('should fail if popup was rejected', async () => {
|
||||
const mockOauth = new MockOAuthApi();
|
||||
const helper = new AuthHelper({
|
||||
const helper = new DefaultAuthConnector({
|
||||
...defaultOptions,
|
||||
oauthRequestApi: mockOauth,
|
||||
});
|
||||
@@ -101,7 +101,7 @@ describe('AuthHelper', () => {
|
||||
scopes: 'a b',
|
||||
expiresInSeconds: 3600,
|
||||
});
|
||||
const helper = new AuthHelper({
|
||||
const helper = new DefaultAuthConnector({
|
||||
...defaultOptions,
|
||||
oauthRequestApi: mockOauth,
|
||||
});
|
||||
+8
-1
@@ -17,6 +17,7 @@
|
||||
import { AuthRequester } from '../../..';
|
||||
import { OAuthRequestApi, AuthProvider } from '../../../definitions';
|
||||
import { showLoginPopup } from '../loginPopup';
|
||||
import { AuthConnector } from './types';
|
||||
|
||||
const DEFAULT_BASE_PATH = '/api/auth/';
|
||||
|
||||
@@ -30,7 +31,13 @@ type Options<AuthSession> = {
|
||||
sessionTransform?(response: any): AuthSession | Promise<AuthSession>;
|
||||
};
|
||||
|
||||
export class AuthHelper<AuthSession> implements AuthHelper<AuthSession> {
|
||||
/**
|
||||
* DefaultAuthConnector is the default auth connector in Backstage. It talks to the
|
||||
* backend auth plugin through the standardized API, and requests user permission
|
||||
* via the OAuthRequestApi.
|
||||
*/
|
||||
export class DefaultAuthConnector<AuthSession>
|
||||
implements AuthConnector<AuthSession> {
|
||||
private readonly apiOrigin: string;
|
||||
private readonly basePath: string;
|
||||
private readonly providerPath: string;
|
||||
+3
-3
@@ -14,11 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import MockAuthHelper, { mockAccessToken } from './MockAuthHelper';
|
||||
import { MockAuthConnector, mockAccessToken } from './MockAuthConnector';
|
||||
|
||||
describe('MockAuthHelper', () => {
|
||||
describe('MockAuthConnector', () => {
|
||||
it('should return mock tokens', async () => {
|
||||
const helper = new MockAuthHelper();
|
||||
const helper = new MockAuthConnector();
|
||||
|
||||
await expect(helper.createSession()).resolves.toEqual({
|
||||
accessToken: mockAccessToken,
|
||||
+2
-2
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { GenericAuthHelper } from './types';
|
||||
import { AuthConnector } from './types';
|
||||
|
||||
export const mockAccessToken = 'mock-access-token';
|
||||
|
||||
@@ -30,7 +30,7 @@ const defaultMockSession: MockSession = {
|
||||
scopes: 'profile email',
|
||||
};
|
||||
|
||||
export default class MockAuthHelper implements GenericAuthHelper<MockSession> {
|
||||
export class MockAuthConnector implements AuthConnector<MockSession> {
|
||||
constructor(private readonly mockSession: MockSession = defaultMockSession) {}
|
||||
|
||||
async refreshSession() {
|
||||
+1
-1
@@ -14,5 +14,5 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { AuthHelper } from './AuthHelper';
|
||||
export { DefaultAuthConnector } from './DefaultAuthConnector';
|
||||
export * from './types';
|
||||
+5
-1
@@ -19,7 +19,11 @@ export type BaseAuthSession = {
|
||||
expiresAt: Date;
|
||||
};
|
||||
|
||||
export type GenericAuthHelper<AuthSession> = {
|
||||
/**
|
||||
* An AuthConnector is responsible for realizing auth session actions
|
||||
* by for example communicating with a backend or interacting with the user.
|
||||
*/
|
||||
export type AuthConnector<AuthSession> = {
|
||||
refreshSession(): Promise<AuthSession>;
|
||||
removeSession(): Promise<void>;
|
||||
createSession(scopes: Set<string>): Promise<AuthSession>;
|
||||
+6
-6
@@ -24,7 +24,7 @@ describe('RefreshingAuthSessionManager', () => {
|
||||
const createSession = jest.fn().mockResolvedValue({ expiresAt: theFuture });
|
||||
const refreshSession = jest.fn().mockRejectedValue(new Error('NOPE'));
|
||||
const manager = new RefreshingAuthSessionManager({
|
||||
helper: { createSession, refreshSession },
|
||||
connector: { createSession, refreshSession },
|
||||
} as any);
|
||||
|
||||
await manager.getSession({});
|
||||
@@ -40,7 +40,7 @@ describe('RefreshingAuthSessionManager', () => {
|
||||
const createSession = jest.fn();
|
||||
const refreshSession = jest.fn().mockRejectedValue(new Error('NOPE'));
|
||||
const manager = new RefreshingAuthSessionManager({
|
||||
helper: { createSession, refreshSession },
|
||||
connector: { createSession, refreshSession },
|
||||
} as any);
|
||||
|
||||
createSession.mockResolvedValue({
|
||||
@@ -64,7 +64,7 @@ describe('RefreshingAuthSessionManager', () => {
|
||||
.mockRejectedValueOnce(new Error('NOPE'))
|
||||
.mockResolvedValue({ scopes: new Set(['a']) });
|
||||
const manager = new RefreshingAuthSessionManager({
|
||||
helper: { createSession, refreshSession },
|
||||
connector: { createSession, refreshSession },
|
||||
} as any);
|
||||
|
||||
createSession.mockResolvedValue({
|
||||
@@ -85,7 +85,7 @@ describe('RefreshingAuthSessionManager', () => {
|
||||
const createSession = jest.fn();
|
||||
const refreshSession = jest.fn().mockRejectedValue(new Error('NOPE'));
|
||||
const manager = new RefreshingAuthSessionManager({
|
||||
helper: { createSession, refreshSession },
|
||||
connector: { createSession, refreshSession },
|
||||
} as any);
|
||||
|
||||
createSession.mockRejectedValueOnce(new Error('some error'));
|
||||
@@ -98,7 +98,7 @@ describe('RefreshingAuthSessionManager', () => {
|
||||
const createSession = jest.fn();
|
||||
const refreshSession = jest.fn().mockRejectedValue(new Error('NOPE'));
|
||||
const manager = new RefreshingAuthSessionManager({
|
||||
helper: { createSession, refreshSession },
|
||||
connector: { createSession, refreshSession },
|
||||
} as any);
|
||||
|
||||
expect(await manager.getSession({ optional: true })).toBe(undefined);
|
||||
@@ -118,7 +118,7 @@ describe('RefreshingAuthSessionManager', () => {
|
||||
|
||||
const removeSession = jest.fn();
|
||||
const manager = new RefreshingAuthSessionManager({
|
||||
helper: { removeSession },
|
||||
connector: { removeSession },
|
||||
} as any);
|
||||
|
||||
await manager.removeSession();
|
||||
|
||||
+8
-8
@@ -16,10 +16,10 @@
|
||||
|
||||
import { hasScopes } from '../../OAuthRequestManager/OAuthPendingRequests';
|
||||
import { SessionManager } from './types';
|
||||
import { BaseAuthSession, GenericAuthHelper } from '../AuthHelper';
|
||||
import { BaseAuthSession, AuthConnector } from '../AuthConnector';
|
||||
|
||||
type Options<AuthSession extends BaseAuthSession> = {
|
||||
helper: GenericAuthHelper<AuthSession>;
|
||||
connector: AuthConnector<AuthSession>;
|
||||
defaultScopes?: Set<string>;
|
||||
};
|
||||
|
||||
@@ -29,16 +29,16 @@ type Options<AuthSession extends BaseAuthSession> = {
|
||||
*/
|
||||
export class RefreshingAuthSessionManager<AuthSession extends BaseAuthSession>
|
||||
implements SessionManager<AuthSession> {
|
||||
private readonly helper: GenericAuthHelper<AuthSession>;
|
||||
private readonly connector: AuthConnector<AuthSession>;
|
||||
private readonly defaultScopes?: Set<string>;
|
||||
|
||||
private refreshPromise?: Promise<AuthSession>;
|
||||
private currentSession: AuthSession | undefined;
|
||||
|
||||
constructor(options: Options<AuthSession>) {
|
||||
const { helper, defaultScopes = new Set() } = options;
|
||||
const { connector, defaultScopes = new Set() } = options;
|
||||
|
||||
this.helper = helper;
|
||||
this.connector = connector;
|
||||
this.defaultScopes = defaultScopes;
|
||||
}
|
||||
|
||||
@@ -92,14 +92,14 @@ export class RefreshingAuthSessionManager<AuthSession extends BaseAuthSession>
|
||||
}
|
||||
|
||||
// We can call authRequester multiple times, the returned session will contain all requested scopes.
|
||||
this.currentSession = await this.helper.createSession(
|
||||
this.currentSession = await this.connector.createSession(
|
||||
this.getExtendedScope(options.scope),
|
||||
);
|
||||
return this.currentSession;
|
||||
}
|
||||
|
||||
async removeSession() {
|
||||
await this.helper.removeSession();
|
||||
await this.connector.removeSession();
|
||||
window.location.reload(); // TODO(Rugvip): make this work without reload?
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ export class RefreshingAuthSessionManager<AuthSession extends BaseAuthSession>
|
||||
return this.refreshPromise;
|
||||
}
|
||||
|
||||
this.refreshPromise = this.helper.refreshSession();
|
||||
this.refreshPromise = this.connector.refreshSession();
|
||||
|
||||
try {
|
||||
return await this.refreshPromise;
|
||||
|
||||
Reference in New Issue
Block a user