UNPKG

16.4 kBTypeScriptView Raw
1/**
2 * The type of the configuration object used to create a `OAuth2PopupFlow`
3 *
4 * Each property has a JSDOC description to explain what it does.
5 */
6export interface OAuth2PopupFlowOptions<TokenPayload extends {
7 exp: number;
8}> {
9 /**
10 * REQUIRED
11 * The full URI of the authorization endpoint provided by the authorization server.
12 *
13 * e.g. `https://example.com/oauth/authorize`
14 */
15 authorizationUri: string;
16 /**
17 * REQUIRED
18 * The client ID of your application provided by the authorization server.
19 *
20 * This client ID is sent to the authorization server using `authorizationUrl` endpoint in the
21 * query portion of the URL along with the other parameters.
22 * This value will be URL encoded like so:
23 *
24 * `https://example.com/oauth/authorize?client_id=SOME_CLIENT_ID_VALUE...`
25 */
26 clientId: string;
27 /**
28 * REQUIRED
29 * The URI that the authorization server will to redirect after the user has been authenticated.
30 * This redirect URI *must* be a URI from *your application* and it must also be registered with
31 * the authorization server. Some authorities call this a "callback URLs" or "login URLs" etc.
32 *
33 * > e.g. `http://localhost:4200/redirect` for local testing
34 * >
35 * > or `https://my-application.com/redirect` for prod
36 *
37 * This redirect URI is sent to the authorization server using `authorizationUrl` endpoint in the
38 * query portion of the URL along with the other parameters.
39 * This value will be URL encoded like so:
40 *
41 * `https://example.com/oauth/authorize?redirect_URI=http%3A%2F%2Flocalhost%2Fredirect...`
42 */
43 redirectUri: string;
44 /**
45 * REQUIRED
46 * A list permission separated by spaces that is the scope of permissions your application is
47 * requesting from the authorization server. If the user is logging in the first time, it may ask
48 * them to approve those permission before authorizing your application.
49 *
50 * > e.g. `openid profile`
51 *
52 * The scopes are sent to the authorization server using `authorizationUrl` endpoint in the
53 * query portion of the URL along with the other parameters.
54 * This value will be URL encoded like so:
55 *
56 * `https://example.com/oauth/authorize?scope=openid%20profile...`
57 */
58 scope: string;
59 /**
60 * OPTIONAL
61 * `response_type` is an argument to be passed to the authorization server via the
62 * `authorizationUri` endpoint in the query portion of the URL.
63 *
64 * Most implementations of oauth2 use the default value of `token` to tell the authorization
65 * server to start the implicit grant flow but you may override that value with this option.
66 *
67 * For example, Auth0--an OAuth2 authority/authorization server--requires the value `id_token`
68 * instead of `token` for the implicit flow.
69 *
70 * The response type is sent to the authorization server using `authorizationUrl` endpoint in the
71 * query portion of the URL along with the other parameters.
72 * This value will be URL encoded like so:
73 *
74 * `https://example.com/oauth/authorize?response_type=token...`
75 */
76 responseType?: string;
77 /**
78 * OPTIONAL
79 * The key used to save the token in the given storage. The default key is `token` so the token
80 * would be persisted in `localStorage.getItem('token')` if `localStorage` was the configured
81 * `Storage`.
82 */
83 accessTokenStorageKey?: string;
84 /**
85 * OPTIONAL
86 * During `handleRedirect`, the method will try to parse `window.location.hash` to an object using
87 * `OAuth2PopupFlow.decodeUriToObject`. After that object has been decoded, this property
88 * determines the key to use that will retrieve the token from that object.
89 *
90 * By default it is `access_token` but you you may need to change that e.g. Auth0 uses `id_token`.
91 */
92 accessTokenResponseKey?: string;
93 /**
94 * OPTIONAL
95 * The storage implementation of choice. It can be `localStorage` or `sessionStorage` or something
96 * else. By default, this is `localStorage` and `localStorage` is the preferred `Storage`.
97 */
98 storage?: Storage;
99 /**
100 * OPTIONAL
101 * The `authenticated` method periodically checks `loggedIn()` and resolves when `loggedIn()`
102 * returns `true`.
103 *
104 * This property is how long it will wait between checks. By default it is `200`.
105 */
106 pollingTime?: number;
107 /**
108 * OPTIONAL
109 * Some oauth authorities require additional parameters to be passed to the `authorizationUri`
110 * URL in order for the implicit grant flow to work.
111 *
112 * For example: [Auth0--an OAuth2 authority/authorization server--requires the parameters
113 * `nonce`][0]
114 * be passed along with every call to the `authorizationUri`. You can do that like so:
115 *
116 * ```ts
117 * const auth = OAuth2PopupFlow({
118 * authorizationUri: 'https://example.com/oauth/authorize',
119 * clientId: 'foo_client',
120 * redirectUri: 'http://localhost:8080/redirect',
121 * scope: 'openid profile',
122 * // this can be a function or static object
123 * additionalAuthorizationParameters: () => {
124 * // in prod, consider something more cryptographic
125 * const nonce = Math.floor(Math.random() * 1000).toString();
126 * localStorage.setItem('nonce', nonce);
127 * return { nonce };
128 * // `nonce` will now be encoded in the URL like so:
129 * // https://example.com/oauth/authorize?client_id=foo_client...nonce=1234
130 * },
131 * // the token returned by Auth0, has the `nonce` in the payload
132 * // you can add this additional check now
133 * tokenValidator: ({ payload }) => {
134 * const storageNonce = parseInt(localStorage.getItem('nonce'), 10);
135 * const payloadNonce = parseInt(payload.nonce, 10);
136 * return storageNonce === payloadNonce;
137 * },
138 * });
139 * ```
140 *
141 * [0]: https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce
142 */
143 additionalAuthorizationParameters?: (() => {
144 [key: string]: string;
145 }) | {
146 [key: string]: string;
147 };
148 /**
149 * OPTIONAL
150 * This function intercepts the `loggedIn` method and causes it to return early with `false` if
151 * this function itself returns `false`. Use this function to validate claims in the token payload
152 * or token.
153 *
154 * [For example: validating the `nonce`:][0]
155 *
156 * ```ts
157 * const auth = OAuth2PopupFlow({
158 * authorizationUri: 'https://example.com/oauth/authorize',
159 * clientId: 'foo_client',
160 * redirectUri: 'http://localhost:8080/redirect',
161 * scope: 'openid profile',
162 * // this can be a function or static object
163 * additionalAuthorizationParameters: () => {
164 * // in prod, consider something more cryptographic
165 * const nonce = Math.floor(Math.random() * 1000).toString();
166 * localStorage.setItem('nonce', nonce);
167 * return { nonce };
168 * // `nonce` will now be encoded in the URL like so:
169 * // https://example.com/oauth/authorize?client_id=foo_client...nonce=1234
170 * },
171 * // the token returned by Auth0, has the `nonce` in the payload
172 * // you can add this additional check now
173 * tokenValidator: ({ payload }) => {
174 * const storageNonce = parseInt(localStorage.getItem('nonce'), 10);
175 * const payloadNonce = parseInt(payload.nonce, 10);
176 * return storageNonce === payloadNonce;
177 * },
178 * });
179 * ```
180 *
181 * [0]: https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce
182 */
183 tokenValidator?: (options: {
184 payload: TokenPayload;
185 token: string;
186 }) => boolean;
187 /**
188 * OPTIONAL
189 * A hook that runs in `tryLoginPopup` before any popup is opened. This function can return a
190 * `Promise` and the popup will not open until it resolves.
191 *
192 * A typical use case would be to wait a certain amount of time before opening the popup to let
193 * the user see why the popup is happening.
194 */
195 beforePopup?: () => any | Promise<any>;
196 /**
197 * OPTIONAL
198 * A hook that runs in `handleRedirect` that takes in the result of the hash payload from the
199 * authorization server. Use this hook to grab more from the response or to debug the response
200 * from the authorization URL.
201 */
202 afterResponse?: (authorizationResponse: {
203 [key: string]: string | undefined;
204 }) => void;
205}
206declare const FixedTypesOAuth2PopupFlow: <TokenPayload extends {
207 exp: number;
208}>(opts: OAuth2PopupFlowOptions<TokenPayload>) => Pick<{
209 /**
210 * REQUIRED
211 * The full URI of the authorization endpoint provided by the authorization server.
212 *
213 * e.g. `https://example.com/oauth/authorize`
214 */
215 authorizationUri: string;
216 /**
217 * REQUIRED
218 * The client ID of your application provided by the authorization server.
219 *
220 * This client ID is sent to the authorization server using `authorizationUrl` endpoint in the
221 * query portion of the URL along with the other parameters.
222 * This value will be URL encoded like so:
223 *
224 * `https://example.com/oauth/authorize?client_id=SOME_CLIENT_ID_VALUE...`
225 */
226 clientId: string;
227 /**
228 * REQUIRED
229 * The URI that the authorization server will to redirect after the user has been authenticated.
230 * This redirect URI *must* be a URI from *your application* and it must also be registered with
231 * the authorization server. Some authorities call this a "callback URLs" or "login URLs" etc.
232 *
233 * > e.g. `http://localhost:4200/redirect` for local testing
234 * >
235 * > or `https://my-application.com/redirect` for prod
236 *
237 * This redirect URI is sent to the authorization server using `authorizationUrl` endpoint in the
238 * query portion of the URL along with the other parameters.
239 * This value will be URL encoded like so:
240 *
241 * `https://example.com/oauth/authorize?redirect_URI=http%3A%2F%2Flocalhost%2Fredirect...`
242 */
243 redirectUri: string;
244 /**
245 * REQUIRED
246 * A list permission separated by spaces that is the scope of permissions your application is
247 * requesting from the authorization server. If the user is logging in the first time, it may ask
248 * them to approve those permission before authorizing your application.
249 *
250 * > e.g. `openid profile`
251 *
252 * The scopes are sent to the authorization server using `authorizationUrl` endpoint in the
253 * query portion of the URL along with the other parameters.
254 * This value will be URL encoded like so:
255 *
256 * `https://example.com/oauth/authorize?scope=openid%20profile...`
257 */
258 scope: string;
259 /**
260 * OPTIONAL
261 * Some oauth authorities require additional parameters to be passed to the `authorizationUri`
262 * URL in order for the implicit grant flow to work.
263 *
264 * For example: [Auth0--an OAuth2 authority/authorization server--requires the parameters
265 * `nonce`][0]
266 * be passed along with every call to the `authorizationUri`. You can do that like so:
267 *
268 * ```ts
269 * const auth = OAuth2PopupFlow({
270 * authorizationUri: 'https://example.com/oauth/authorize',
271 * clientId: 'foo_client',
272 * redirectUri: 'http://localhost:8080/redirect',
273 * scope: 'openid profile',
274 * // this can be a function or static object
275 * additionalAuthorizationParameters: () => {
276 * // in prod, consider something more cryptographic
277 * const nonce = Math.floor(Math.random() * 1000).toString();
278 * localStorage.setItem('nonce', nonce);
279 * return { nonce };
280 * // `nonce` will now be encoded in the URL like so:
281 * // https://example.com/oauth/authorize?client_id=foo_client...nonce=1234
282 * },
283 * // the token returned by Auth0, has the `nonce` in the payload
284 * // you can add this additional check now
285 * tokenValidator: ({ payload }) => {
286 * const storageNonce = parseInt(localStorage.getItem('nonce'), 10);
287 * const payloadNonce = parseInt(payload.nonce, 10);
288 * return storageNonce === payloadNonce;
289 * },
290 * });
291 * ```
292 *
293 * [0]: https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce
294 */
295 additionalAuthorizationParameters?: {
296 [key: string]: string;
297 } | (() => {
298 [key: string]: string;
299 }) | undefined;
300 /**
301 * OPTIONAL
302 * This function intercepts the `loggedIn` method and causes it to return early with `false` if
303 * this function itself returns `false`. Use this function to validate claims in the token payload
304 * or token.
305 *
306 * [For example: validating the `nonce`:][0]
307 *
308 * ```ts
309 * const auth = OAuth2PopupFlow({
310 * authorizationUri: 'https://example.com/oauth/authorize',
311 * clientId: 'foo_client',
312 * redirectUri: 'http://localhost:8080/redirect',
313 * scope: 'openid profile',
314 * // this can be a function or static object
315 * additionalAuthorizationParameters: () => {
316 * // in prod, consider something more cryptographic
317 * const nonce = Math.floor(Math.random() * 1000).toString();
318 * localStorage.setItem('nonce', nonce);
319 * return { nonce };
320 * // `nonce` will now be encoded in the URL like so:
321 * // https://example.com/oauth/authorize?client_id=foo_client...nonce=1234
322 * },
323 * // the token returned by Auth0, has the `nonce` in the payload
324 * // you can add this additional check now
325 * tokenValidator: ({ payload }) => {
326 * const storageNonce = parseInt(localStorage.getItem('nonce'), 10);
327 * const payloadNonce = parseInt(payload.nonce, 10);
328 * return storageNonce === payloadNonce;
329 * },
330 * });
331 * ```
332 *
333 * [0]: https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce
334 */
335 tokenValidator?: ((options: {
336 payload: {
337 exp: number;
338 };
339 token: string;
340 }) => boolean) | undefined;
341 /**
342 * OPTIONAL
343 * A hook that runs in `tryLoginPopup` before any popup is opened. This function can return a
344 * `Promise` and the popup will not open until it resolves.
345 *
346 * A typical use case would be to wait a certain amount of time before opening the popup to let
347 * the user see why the popup is happening.
348 */
349 beforePopup?: (() => any) | undefined;
350 /**
351 * OPTIONAL
352 * A hook that runs in `handleRedirect` that takes in the result of the hash payload from the
353 * authorization server. Use this hook to grab more from the response or to debug the response
354 * from the authorization URL.
355 */
356 afterResponse?: ((authorizationResponse: {
357 [key: string]: string | undefined;
358 }) => void) | undefined;
359 responseType: string;
360 accessTokenStorageKey: string;
361 accessTokenResponseKey: string;
362 storage: Storage;
363 pollingTime: number;
364 addEventListener: (type: string, listener: EventListenerOrEventListenerObject) => void;
365 dispatchEvent: (event: Event) => boolean;
366 removeEventListener: (type: string, listener: EventListenerOrEventListenerObject) => void;
367 loggedIn: () => boolean;
368 logout: () => void;
369 tokenExpired: () => boolean;
370 handleRedirect: () => "REDIRECT_URI_MISMATCH" | "FALSY_HASH" | "FALSY_TOKEN" | "SUCCESS";
371 tryLoginPopup: () => Promise<"SUCCESS" | "ALREADY_LOGGED_IN" | "POPUP_FAILED">;
372 authenticated: () => Promise<void>;
373 token: () => Promise<string>;
374 tokenPayload: () => Promise<{
375 exp: number;
376 }>;
377}, "storage" | "responseType" | "token" | "accessTokenStorageKey" | "accessTokenResponseKey" | "pollingTime" | "authorizationUri" | "clientId" | "redirectUri" | "scope" | "additionalAuthorizationParameters" | "tokenValidator" | "beforePopup" | "afterResponse" | "logout" | "addEventListener" | "dispatchEvent" | "removeEventListener" | "loggedIn" | "tokenExpired" | "handleRedirect" | "tryLoginPopup" | "authenticated" | "tokenPayload">;
378export { FixedTypesOAuth2PopupFlow as OAuth2PopupFlow };
379export default FixedTypesOAuth2PopupFlow;