diff --git a/packages/core/src/api/apis/definitions/oauthrequest.ts b/packages/core/src/api/apis/definitions/oauthrequest.ts index b31b828183..09e5f77718 100644 --- a/packages/core/src/api/apis/definitions/oauthrequest.ts +++ b/packages/core/src/api/apis/definitions/oauthrequest.ts @@ -63,10 +63,10 @@ export type LoginPopupOptions = { /** * Information about the auth provider that we're requesting a login towards. * - * This should be show to the user so that they can be informed about what login is being requested + * This should be shown to the user so that they can be informed about what login is being requested * before a popup is shown. */ -export type AuthProviderInfo = { +export type AuthProvider = { /** * Title for the auth provider, for example "GitHub" */ @@ -82,39 +82,45 @@ export type AuthProviderInfo = { * Describes how to handle auth requests. Both how to show them to the user, and what to do when * the user accesses the auth request. */ -export type AuthRequesterOptions = { +export type AuthRequesterOptions = { /** * Information about the auth provider, which will be forwarded to auth requests. */ - info: AuthProviderInfo; + provider: AuthProvider; /** * Implementation of the auth flow, which will be called synchronously when - * triggerAuth() is called on an auth requests. + * trigger() is called on an auth requests. */ - authHandler(scope: OAuthScopes): Promise; + onAuthRequest(scope: OAuthScopes): Promise; }; /** * Function used to trigger new auth requests for a set of scopes. * - * The returned promise will resolve to the same value returned by the authHandler in the + * The returned promise will resolve to the same value returned by the onAuthRequest in the * AuthRequesterOptions. Or rejected, if the request is rejected. * * This function can be called multiple times before the promise resolves. All calls - * will be merged into one request, and the scopes forwarded to the authHandler will be the + * will be merged into one request, and the scopes forwarded to the onAuthRequest will be the * union of all requested scopes. */ -export type AuthRequester = (scope: OAuthScopes) => Promise; +export type AuthRequester = ( + scope: OAuthScopes, +) => Promise; /** - * An auth request for a single auth provider. + * An pending auth request for a single auth provider. The request will remain in this pending + * state until either reject() or trigger() is called. + * + * Any new requests for the same provider are merged into the existing pending request, meaning + * there will only ever be a single pending request for a given provider. */ -export type AuthRequest = { +export type PendingAuthRequest = { /** * Information about the auth provider, as given in the AuthRequesterOptions */ - info: AuthProviderInfo; + provider: AuthProvider; /** * Rejects the request, causing all pending AuthRequester calls to fail with "RejectedError". @@ -122,9 +128,11 @@ export type AuthRequest = { reject: () => void; /** - * Synchronously calls the auth handler with all scope currently in the request. + * Trigger the auth request to continue the auth flow, by for example showing a popup. + * + * Synchronously calls onAuthRequest with all scope currently in the request. */ - triggerAuth(): Promise; + trigger(): Promise; }; /** @@ -136,6 +144,8 @@ export type OAuthRequestApi = { * * The redirect handler of the flow should use postMessage to communicate back * to the app window. + * + * The returned promise resolves to the contents of the message that was posted from the auth popup. */ showLoginPopup(options: LoginPopupOptions): Promise; @@ -143,7 +153,7 @@ export type OAuthRequestApi = { * A utility for showing login popups or similar things, and merging together multiple requests for * different scopes into one request that inclues all scopes. * - * The passed in options provide information about the login provider, and how handle auth requests. + * The passed in options provide information about the login provider, and how to handle auth requests. * * The returned AuthRequester function is used to request login with new scopes. These requests * are merged together and forwarded to the auth handler, as soon as a consumer of auth requests @@ -151,10 +161,12 @@ export type OAuthRequestApi = { * * See AuthRequesterOptions, AuthRequester, and handleAuthRequests for more info. */ - createAuthRequester(options: AuthRequesterOptions): AuthRequester; + createAuthRequester( + options: AuthRequesterOptions, + ): AuthRequester; /** - * Subscribes as a handler of auth requests. The returned observable will emit all + * Observers panding auth requests. The returned observable will emit all * current active auth request, at most one for each created auth requester. * * Each request has its own info about the login provider, forwarded from the auth requester options. @@ -162,9 +174,9 @@ export type OAuthRequestApi = { * Depending on user interaction, the request should either be rejected, or used to trigger the auth handler. * If the request is rejected, all pending AuthRequester calls will fail with a "RejectedError". * If a auth is triggered, and the auth handler resolves successfully, then all currently pending - * AuthRequester calls will resolve to the value returned by the authHandler call. + * AuthRequester calls will resolve to the value returned by the onAuthRequest call. */ - handleAuthRequests(): Observable; + authRequest$(): Observable; }; export const oauthRequestApiRef = new ApiRef({ diff --git a/packages/core/src/api/apis/implementations/OAuthRequestManager/OAuthPendingRequests.ts b/packages/core/src/api/apis/implementations/OAuthRequestManager/OAuthPendingRequests.ts index bc1b33ca5e..904acecf9f 100644 --- a/packages/core/src/api/apis/implementations/OAuthRequestManager/OAuthPendingRequests.ts +++ b/packages/core/src/api/apis/implementations/OAuthRequestManager/OAuthPendingRequests.ts @@ -38,8 +38,8 @@ export type OAuthPendingRequestsApi = { /** * The OAuthPendingRequests class is a utility for managing and observing - * a stream of requests for oauth scopes, and resolving them correctly once - * requests are fulfilled. + * a stream of requests for oauth scopes for a single provider, and resolving + * them correctly once requests are fulfilled. */ export class OAuthPendingRequests implements OAuthPendingRequestsApi { diff --git a/packages/core/src/api/apis/implementations/OAuthRequestManager/OAuthRequestManager.ts b/packages/core/src/api/apis/implementations/OAuthRequestManager/OAuthRequestManager.ts index c8cfacd161..dd31a4b33c 100644 --- a/packages/core/src/api/apis/implementations/OAuthRequestManager/OAuthRequestManager.ts +++ b/packages/core/src/api/apis/implementations/OAuthRequestManager/OAuthRequestManager.ts @@ -17,7 +17,7 @@ import { OAuthRequestApi, LoginPopupOptions, - AuthRequest, + PendingAuthRequest, AuthRequester, AuthRequesterOptions, } from '../../definitions/oauthrequest'; @@ -29,18 +29,18 @@ import { OAuthPendingRequests, PendingRequest } from './OAuthPendingRequests'; * * The purpose of this class and the API is to read a stream of incoming requests * of OAuth access tokens from different providers with varying scope, and funnel - * them all together into a single requests for each OAuth provider. + * them all together into a single request for each OAuth provider. */ export class OAuthRequestManager implements OAuthRequestApi { - private readonly requests$: Observable; + private readonly request$: Observable; private readonly observers = new Set< - ZenObservable.SubscriptionObserver + ZenObservable.SubscriptionObserver >(); - private currentRequests: AuthRequest[] = []; + private currentRequests: PendingAuthRequest[] = []; private handlerCount = 0; constructor() { - this.requests$ = new Observable((observer) => { + this.request$ = new Observable((observer) => { observer.next(this.currentRequests); this.observers.add(observer); @@ -79,16 +79,16 @@ export class OAuthRequestManager implements OAuthRequestApi { private makeAuthRequest( request: PendingRequest, options: AuthRequesterOptions, - ): AuthRequest | undefined { + ): PendingAuthRequest | undefined { const { scopes } = request; if (!scopes) { return undefined; } return { - info: options.info, - triggerAuth: async () => { - const result = await options.authHandler(scopes); + provider: options.provider, + trigger: async () => { + const result = await options.onAuthRequest(scopes); request.resolve(result); }, reject: () => { @@ -99,8 +99,8 @@ export class OAuthRequestManager implements OAuthRequestApi { }; } - handleAuthRequests(): Observable { - return this.requests$; + authRequest$(): Observable { + return this.request$; } async showLoginPopup(options: LoginPopupOptions): Promise { diff --git a/packages/core/src/api/types.ts b/packages/core/src/api/types.ts index 28a6155017..09f0bc11ae 100644 --- a/packages/core/src/api/types.ts +++ b/packages/core/src/api/types.ts @@ -32,7 +32,7 @@ export type Observer = { */ export type Subscription = { /** - * CAncels the subscription + * Cancels the subscription */ unsubscribe(): void; diff --git a/packages/core/src/components/OAuthRequestDialog/LoginRequestListItem.tsx b/packages/core/src/components/OAuthRequestDialog/LoginRequestListItem.tsx index 56d69aa814..8e3d98c998 100644 --- a/packages/core/src/components/OAuthRequestDialog/LoginRequestListItem.tsx +++ b/packages/core/src/components/OAuthRequestDialog/LoginRequestListItem.tsx @@ -23,7 +23,7 @@ import { Theme, } from '@material-ui/core'; import React, { FC, useState } from 'react'; -import { AuthRequest } from '../../api'; +import { PendingAuthRequest } from '../../api'; const useItemStyles = makeStyles((theme) => ({ root: { @@ -32,7 +32,7 @@ const useItemStyles = makeStyles((theme) => ({ })); type RowProps = { - request: AuthRequest; + request: PendingAuthRequest; busy: boolean; setBusy: (busy: boolean) => void; }; @@ -44,7 +44,7 @@ const LoginRequestListItem: FC = ({ request, busy, setBusy }) => { const handleContinue = async () => { setBusy(true); try { - await request.triggerAuth(); + await request.trigger(); } catch (e) { setError(e); } finally { @@ -52,7 +52,7 @@ const LoginRequestListItem: FC = ({ request, busy, setBusy }) => { } }; - const IconComponent = request.info.icon; + const IconComponent = request.provider.icon; return ( = ({ request, busy, setBusy }) => { diff --git a/packages/core/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx b/packages/core/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx index 2a105fe5e3..617cce2aee 100644 --- a/packages/core/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx +++ b/packages/core/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx @@ -48,7 +48,7 @@ export const OAuthRequestDialog: FC = () => { const [busy, setBusy] = useState(false); const oauthRequestApi = useApi(oauthRequestApiRef); const requests = useObservable( - useMemo(() => oauthRequestApi.handleAuthRequests(), [oauthRequestApi]), + useMemo(() => oauthRequestApi.authRequest$(), [oauthRequestApi]), [], ); @@ -71,7 +71,7 @@ export const OAuthRequestDialog: FC = () => { {requests.map((request) => (