packages/core: naming and docs updates for OAuthRequest API
This commit is contained in:
@@ -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<T> = {
|
||||
export type AuthRequesterOptions<AuthResponse> = {
|
||||
/**
|
||||
* 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<T>;
|
||||
onAuthRequest(scope: OAuthScopes): Promise<AuthResponse>;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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<T> = (scope: OAuthScopes) => Promise<T>;
|
||||
export type AuthRequester<AuthResponse> = (
|
||||
scope: OAuthScopes,
|
||||
) => Promise<AuthResponse>;
|
||||
|
||||
/**
|
||||
* 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<void>;
|
||||
trigger(): Promise<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -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<any>;
|
||||
|
||||
@@ -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<T>(options: AuthRequesterOptions<T>): AuthRequester<T>;
|
||||
createAuthRequester<AuthResponse>(
|
||||
options: AuthRequesterOptions<AuthResponse>,
|
||||
): AuthRequester<AuthResponse>;
|
||||
|
||||
/**
|
||||
* 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[]>;
|
||||
authRequest$(): Observable<PendingAuthRequest[]>;
|
||||
};
|
||||
|
||||
export const oauthRequestApiRef = new ApiRef<OAuthRequestApi>({
|
||||
|
||||
+2
-2
@@ -38,8 +38,8 @@ export type OAuthPendingRequestsApi<ResultType> = {
|
||||
|
||||
/**
|
||||
* 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<ResultType>
|
||||
implements OAuthPendingRequestsApi<ResultType> {
|
||||
|
||||
+12
-12
@@ -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<AuthRequest[]>;
|
||||
private readonly request$: Observable<PendingAuthRequest[]>;
|
||||
private readonly observers = new Set<
|
||||
ZenObservable.SubscriptionObserver<AuthRequest[]>
|
||||
ZenObservable.SubscriptionObserver<PendingAuthRequest[]>
|
||||
>();
|
||||
private currentRequests: AuthRequest[] = [];
|
||||
private currentRequests: PendingAuthRequest[] = [];
|
||||
private handlerCount = 0;
|
||||
|
||||
constructor() {
|
||||
this.requests$ = new Observable<AuthRequest[]>((observer) => {
|
||||
this.request$ = new Observable<PendingAuthRequest[]>((observer) => {
|
||||
observer.next(this.currentRequests);
|
||||
|
||||
this.observers.add(observer);
|
||||
@@ -79,16 +79,16 @@ export class OAuthRequestManager implements OAuthRequestApi {
|
||||
private makeAuthRequest(
|
||||
request: PendingRequest<any>,
|
||||
options: AuthRequesterOptions<any>,
|
||||
): 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<AuthRequest[]> {
|
||||
return this.requests$;
|
||||
authRequest$(): Observable<PendingAuthRequest[]> {
|
||||
return this.request$;
|
||||
}
|
||||
|
||||
async showLoginPopup(options: LoginPopupOptions): Promise<any> {
|
||||
|
||||
@@ -32,7 +32,7 @@ export type Observer<T> = {
|
||||
*/
|
||||
export type Subscription = {
|
||||
/**
|
||||
* CAncels the subscription
|
||||
* Cancels the subscription
|
||||
*/
|
||||
unsubscribe(): void;
|
||||
|
||||
|
||||
@@ -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>((theme) => ({
|
||||
root: {
|
||||
@@ -32,7 +32,7 @@ const useItemStyles = makeStyles<Theme>((theme) => ({
|
||||
}));
|
||||
|
||||
type RowProps = {
|
||||
request: AuthRequest;
|
||||
request: PendingAuthRequest;
|
||||
busy: boolean;
|
||||
setBusy: (busy: boolean) => void;
|
||||
};
|
||||
@@ -44,7 +44,7 @@ const LoginRequestListItem: FC<RowProps> = ({ 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<RowProps> = ({ request, busy, setBusy }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const IconComponent = request.info.icon;
|
||||
const IconComponent = request.provider.icon;
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
@@ -65,7 +65,7 @@ const LoginRequestListItem: FC<RowProps> = ({ request, busy, setBusy }) => {
|
||||
<IconComponent fontSize="large" />
|
||||
</ListItemAvatar>
|
||||
<ListItemText
|
||||
primary={request.info.title}
|
||||
primary={request.provider.title}
|
||||
secondary={
|
||||
error && (
|
||||
<Typography color="error">
|
||||
|
||||
@@ -48,7 +48,7 @@ export const OAuthRequestDialog: FC<OAuthRequestDialogProps> = () => {
|
||||
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<OAuthRequestDialogProps> = () => {
|
||||
<List>
|
||||
{requests.map((request) => (
|
||||
<LoginRequestListItem
|
||||
key={request.info.title}
|
||||
key={request.provider.title}
|
||||
request={request}
|
||||
busy={busy}
|
||||
setBusy={setBusy}
|
||||
|
||||
Reference in New Issue
Block a user