UNPKG

22.2 kBTypeScriptView Raw
1/// <reference types="@adonisjs/application/build/adonis-typings/application" />
2declare module '@ioc:Adonis/Addons/Auth' {
3 import { DateTime } from 'luxon';
4 import { HashersList } from '@ioc:Adonis/Core/Hash';
5 import { QueryClientContract } from '@ioc:Adonis/Lucid/Database';
6 import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
7 import { ApplicationContract } from '@ioc:Adonis/Core/Application';
8 import { DatabaseQueryBuilderContract } from '@ioc:Adonis/Lucid/Database';
9 import { LucidModel, LucidRow, ModelQueryBuilderContract } from '@ioc:Adonis/Lucid/Orm';
10 /**
11 * Unwraps user from the provider user
12 */
13 type UnWrapProviderUser<T> = T extends ProviderUserContract<any> ? Exclude<T['user'], null> : T;
14 /**
15 * Unwraps awaited type from Promise
16 */
17 type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T;
18 /**
19 * Returns the real user from the provider user
20 */
21 export type GetProviderRealUser<Provider extends keyof ProvidersList> = UnWrapProviderUser<Awaited<ReturnType<ProvidersList[Provider]['implementation']['getUserFor']>>>;
22 /**
23 * Provider user works as a bridge between the provider real user
24 * and the guard. It is never exposed to the end-user.
25 */
26 export interface ProviderUserContract<User extends any> {
27 user: User | null;
28 getId(): string | number | null;
29 verifyPassword: (plainPassword: string) => Promise<boolean>;
30 getRememberMeToken(): string | null;
31 setRememberMeToken(token: string): void;
32 }
33 /**
34 * The interface that every provider must implement
35 */
36 export interface UserProviderContract<User extends any> {
37 /**
38 * Return an instance of the user wrapped inside the Provider user contract
39 */
40 getUserFor(user: User): Promise<ProviderUserContract<User>>;
41 /**
42 * Find a user using the primary key value
43 */
44 findById(id: string | number): Promise<ProviderUserContract<User>>;
45 /**
46 * Find a user by searching for their uids
47 */
48 findByUid(uid: string): Promise<ProviderUserContract<User>>;
49 /**
50 * Find a user using the remember me token
51 */
52 findByRememberMeToken(userId: string | number, token: string): Promise<ProviderUserContract<User>>;
53 /**
54 * Update remember token
55 */
56 updateRememberMeToken(authenticatable: ProviderUserContract<User>): Promise<void>;
57 }
58 /**
59 * Shape of the token sent to/read from the tokens provider
60 */
61 export interface ProviderTokenContract {
62 /**
63 * Persisted token value. It is a sha256 hash
64 */
65 tokenHash: string;
66 /**
67 * Token name
68 */
69 name: string;
70 /**
71 * Token type
72 */
73 type: string;
74 /**
75 * UserId for which the token was saved
76 */
77 userId: string | number;
78 /**
79 * Expiry date
80 */
81 expiresAt?: DateTime;
82 /**
83 * All other token details
84 */
85 meta?: any;
86 }
87 /**
88 * Token providers provides the API to create/fetch and delete tokens
89 * for a given user. Any token based implementation can use token
90 * providers, given they only store a single token.
91 */
92 export interface TokenProviderContract {
93 /**
94 * Define a custom connection for the driver in use
95 */
96 setConnection(connection: any): this;
97 /**
98 * Saves the token to some persistance storage and returns an lookup
99 * id. We introduced the concept of lookup ids, since lookups by
100 * cryptographic tokens can have performance impacts on certain
101 * databases.
102 *
103 * Also note that the return lookup id is also prepended to the raw
104 * token, so that we can later extract the id for reads. The
105 * real message is to keep the lookup ids small.
106 */
107 write(token: ProviderTokenContract): Promise<string>;
108 /**
109 * Find token using the lookup id or the token value
110 */
111 read(lookupId: string, token: string, type: string): Promise<ProviderTokenContract | null>;
112 /**
113 * Delete token using the lookup id or the token value
114 */
115 destroy(lookupId: string, type: string): Promise<void>;
116 }
117 /**
118 * Config for the database token provider
119 */
120 export type DatabaseTokenProviderConfig = {
121 driver: 'database';
122 table: string;
123 foreignKey?: string;
124 connection?: string;
125 type?: string;
126 };
127 /**
128 * Config for the redis token provider
129 */
130 export type RedisTokenProviderConfig = {
131 driver: 'redis';
132 redisConnection: string;
133 foreignKey?: string;
134 type?: string;
135 };
136 /**
137 * The shape of the user model accepted by the Lucid provider. The model
138 * must have `password` and `rememberMeToken` attributes.
139 */
140 export type LucidProviderModel = LucidModel & {
141 findForAuth?: <T extends LucidModel>(this: T, uids: string[], value: any) => Promise<InstanceType<T>>;
142 } & {
143 new (): LucidRow & {
144 password?: string;
145 rememberMeToken?: string | null;
146 };
147 };
148 /**
149 * Shape of the lucid provider user builder. It must return [[ProviderUserContract]]
150 */
151 export interface LucidProviderUserBuilder<User extends LucidProviderModel> {
152 new (user: InstanceType<User> | null, config: LucidProviderConfig<User>, ...args: any[]): ProviderUserContract<InstanceType<User>>;
153 }
154 /**
155 * Lucid provider
156 */
157 export interface LucidProviderContract<User extends LucidProviderModel> extends UserProviderContract<InstanceType<User>> {
158 /**
159 * Define a custom connection for all the provider queries
160 */
161 setConnection(connection: string | QueryClientContract): this;
162 /**
163 * Before hooks
164 */
165 before(event: 'findUser', callback: (query: ModelQueryBuilderContract<User>) => Promise<void>): this;
166 /**
167 * After hooks
168 */
169 after(event: 'findUser', callback: (user: InstanceType<User>) => Promise<void>): this;
170 }
171 /**
172 * The config accepted by the Lucid provider
173 */
174 export type LucidProviderConfig<User extends LucidProviderModel> = {
175 driver: 'lucid';
176 model: () => Promise<User> | Promise<{
177 default: User;
178 }>;
179 uids: (keyof InstanceType<User>)[];
180 identifierKey: string;
181 connection?: string;
182 hashDriver?: keyof HashersList;
183 user?: () => Promise<LucidProviderUserBuilder<User>> | Promise<{
184 default: LucidProviderUserBuilder<User>;
185 }>;
186 };
187 /**
188 * Shape of the row returned by the database provider. The table must have `password`
189 * and `remember_me_token` columns.
190 */
191 export type DatabaseProviderRow = {
192 password?: string;
193 remember_me_token?: string;
194 [key: string]: any;
195 };
196 /**
197 * Shape of database provider user builder. It must always returns [[ProviderUserContract]]
198 */
199 export interface DatabaseProviderUserBuilder {
200 new (user: DatabaseProviderRow | null, config: DatabaseProviderConfig, ...args: any[]): ProviderUserContract<DatabaseProviderRow>;
201 }
202 /**
203 * Database provider
204 */
205 export interface DatabaseProviderContract<User extends DatabaseProviderRow> extends UserProviderContract<User> {
206 /**
207 * Define a custom connection for all the provider queries
208 */
209 setConnection(connection: string | QueryClientContract): this;
210 /**
211 * Before hooks
212 */
213 before(event: 'findUser', callback: (query: DatabaseQueryBuilderContract) => Promise<void>): this;
214 /**
215 * After hooks
216 */
217 after(event: 'findUser', callback: (user: DatabaseProviderRow) => Promise<void>): this;
218 }
219 /**
220 * The config accepted by the Database provider
221 */
222 export type DatabaseProviderConfig = {
223 driver: 'database';
224 uids: string[];
225 usersTable: string;
226 identifierKey: string;
227 connection?: string;
228 hashDriver?: keyof HashersList;
229 user?: () => Promise<DatabaseProviderUserBuilder> | Promise<{
230 default: DatabaseProviderUserBuilder;
231 }>;
232 };
233 /**
234 * Request data a guard client can set when making the
235 * testing request
236 */
237 export type ClientRequestData = {
238 session?: Record<string, any>;
239 headers?: Record<string, any>;
240 cookies?: Record<string, any>;
241 };
242 /**
243 * The authentication clients should follow this interface
244 */
245 export interface GuardClientContract<Provider extends keyof ProvidersList> {
246 /**
247 * Login a user
248 */
249 login(user: GetProviderRealUser<Provider>, ...args: any[]): Promise<ClientRequestData>;
250 /**
251 * Logout user
252 */
253 logout(user: GetProviderRealUser<Provider>): Promise<void>;
254 }
255 export interface GuardContract<Provider extends keyof ProvidersList, Guard extends keyof GuardsList> {
256 name: Guard;
257 /**
258 * Reference to the guard config
259 */
260 config: GuardsList[Guard]['config'];
261 /**
262 * Reference to the logged in user.
263 */
264 user?: GetProviderRealUser<Provider>;
265 /**
266 * Find if the user has been logged out in the current request
267 */
268 isLoggedOut: boolean;
269 /**
270 * A boolean to know if user is a guest or not. It is
271 * always opposite of [[isLoggedIn]]
272 */
273 isGuest: boolean;
274 /**
275 * A boolean to know if user is logged in or not
276 */
277 isLoggedIn: boolean;
278 /**
279 * A boolean to know if user is retrieved by authenticating
280 * the current request or not.
281 */
282 isAuthenticated: boolean;
283 /**
284 * Whether or not the authentication has been attempted
285 * for the current request
286 */
287 authenticationAttempted: boolean;
288 /**
289 * Reference to the provider for looking up the user
290 */
291 provider: ProvidersList[Provider]['implementation'];
292 /**
293 * Verify user credentials.
294 */
295 verifyCredentials(uid: string, password: string): Promise<GetProviderRealUser<Provider>>;
296 /**
297 * Attempt to verify user credentials and perform login
298 */
299 attempt(uid: string, password: string, ...args: any[]): Promise<any>;
300 /**
301 * Login a user without any verification
302 */
303 login(user: GetProviderRealUser<Provider>, ...args: any[]): Promise<any>;
304 /**
305 * Login a user using their id
306 */
307 loginViaId(id: string | number, ...args: any[]): Promise<any>;
308 /**
309 * Attempts to authenticate the user for the current HTTP request. An exception
310 * is raised when unable to do so
311 */
312 authenticate(): Promise<GetProviderRealUser<Provider>>;
313 /**
314 * Attempts to authenticate the user for the current HTTP request and supresses
315 * exceptions raised by the [[authenticate]] method and returns a boolean
316 */
317 check(): Promise<boolean>;
318 /**
319 * Logout user
320 */
321 logout(...args: any[]): Promise<void>;
322 /**
323 * Serialize guard to JSON
324 */
325 toJSON(): any;
326 }
327 /**
328 * Shape of data emitted by the login event
329 */
330 export type SessionLoginEventData<Provider extends keyof ProvidersList> = {
331 name: string;
332 user: GetProviderRealUser<Provider>;
333 ctx: HttpContextContract;
334 token: string | null;
335 };
336 /**
337 * Shape of data emitted by the authenticate event
338 */
339 export type SessionAuthenticateEventData<Provider extends keyof ProvidersList> = {
340 name: string;
341 user: GetProviderRealUser<Provider>;
342 ctx: HttpContextContract;
343 viaRemember: boolean;
344 };
345 /**
346 * Shape of the session guard
347 */
348 export interface SessionGuardContract<Provider extends keyof ProvidersList, Name extends keyof GuardsList> extends GuardContract<Provider, Name> {
349 /**
350 * A boolean to know if user is loggedin via remember me token or not.
351 */
352 viaRemember: boolean;
353 /**
354 * Attempt to verify user credentials and perform login
355 */
356 attempt(uid: string, password: string, remember?: boolean): Promise<any>;
357 /**
358 * Login a user without any verification
359 */
360 login(user: GetProviderRealUser<Provider>, remember?: boolean): Promise<any>;
361 /**
362 * Login a user using their id
363 */
364 loginViaId(id: string | number, remember?: boolean): Promise<any>;
365 /**
366 * Logout user
367 */
368 logout(renewRememberToken?: boolean): Promise<void>;
369 }
370 /**
371 * Session client to login users during tests
372 */
373 export interface SessionClientContract<Provider extends keyof ProvidersList> extends GuardClientContract<Provider> {
374 }
375 /**
376 * Shape of session driver config.
377 */
378 export type SessionGuardConfig<Provider extends keyof ProvidersList> = {
379 driver: 'session';
380 provider: ProvidersList[Provider]['config'];
381 };
382 /**
383 * Shape of data emitted by the authenticate event
384 */
385 export type BasicAuthAuthenticateEventData<Provider extends keyof ProvidersList> = {
386 name: string;
387 user: GetProviderRealUser<Provider>;
388 ctx: HttpContextContract;
389 };
390 /**
391 * Shape of the basic auth guard
392 */
393 export interface BasicAuthGuardContract<Provider extends keyof ProvidersList, Name extends keyof GuardsList> extends Omit<GuardContract<Provider, Name>, 'attempt' | 'login' | 'loginViaId' | 'logout'> {
394 }
395 /**
396 * Basic auth client to login users during tests
397 */
398 export interface BasicAuthClientContract<Provider extends keyof ProvidersList> extends GuardClientContract<Provider> {
399 }
400 /**
401 * Shape of basic auth guard config.
402 */
403 export type BasicAuthGuardConfig<Provider extends keyof ProvidersList> = {
404 driver: 'basic';
405 realm?: string;
406 provider: ProvidersList[Provider]['config'];
407 };
408 /**
409 * Opaque token is generated during the login call by the OpaqueTokensGuard
410 */
411 export interface OpaqueTokenContract<User extends any> {
412 /**
413 * Always a bearer token
414 */
415 type: 'bearer';
416 /**
417 * The user for which the token was generated
418 */
419 user: User;
420 /**
421 * Date/time when the token will be expired
422 */
423 expiresAt?: DateTime;
424 /**
425 * Time in seconds until the token is valid
426 */
427 expiresIn?: number;
428 /**
429 * Any meta-data attached with the token
430 */
431 meta: any;
432 /**
433 * Token name
434 */
435 name: string;
436 /**
437 * Token public value
438 */
439 token: string;
440 /**
441 * Token hash (persisted to the db as well)
442 */
443 tokenHash: string;
444 /**
445 * Serialize token
446 */
447 toJSON(): {
448 type: 'bearer';
449 token: string;
450 expires_at?: string;
451 expires_in?: number;
452 };
453 }
454 /**
455 * Login options
456 */
457 export type OATLoginOptions = {
458 name?: string;
459 expiresIn?: number | string;
460 } & {
461 [key: string]: any;
462 };
463 /**
464 * Shape of data emitted by the login event
465 */
466 export type OATLoginEventData<Provider extends keyof ProvidersList> = {
467 name: string;
468 user: GetProviderRealUser<Provider>;
469 ctx: HttpContextContract;
470 token: OpaqueTokenContract<GetProviderRealUser<Provider>>;
471 };
472 /**
473 * Shape of the data emitted by the authenticate event
474 */
475 export type OATAuthenticateEventData<Provider extends keyof ProvidersList> = {
476 name: string;
477 user: GetProviderRealUser<Provider>;
478 ctx: HttpContextContract;
479 token: ProviderTokenContract;
480 };
481 /**
482 * Shape of the OAT guard
483 */
484 export interface OATGuardContract<Provider extends keyof ProvidersList, Name extends keyof GuardsList> extends GuardContract<Provider, Name> {
485 token?: ProviderTokenContract;
486 tokenProvider: TokenProviderContract;
487 /**
488 * Attempt to verify user credentials and perform login
489 */
490 attempt(uid: string, password: string, options?: OATLoginOptions): Promise<OpaqueTokenContract<GetProviderRealUser<Provider>>>;
491 /**
492 * Login a user without any verification
493 */
494 login(user: GetProviderRealUser<Provider>, options?: OATLoginOptions): Promise<OpaqueTokenContract<GetProviderRealUser<Provider>>>;
495 /**
496 * Generate token for a user without any verification
497 */
498 generate(user: GetProviderRealUser<Provider>, options?: OATLoginOptions): Promise<OpaqueTokenContract<GetProviderRealUser<Provider>>>;
499 /**
500 * Alias for logout
501 */
502 revoke(): Promise<void>;
503 /**
504 * Login a user using their id
505 */
506 loginViaId(id: string | number, options?: OATLoginOptions): Promise<OpaqueTokenContract<GetProviderRealUser<Provider>>>;
507 }
508 /**
509 * Oat guard to login users during tests
510 */
511 export interface OATClientContract<Provider extends keyof ProvidersList> extends GuardClientContract<Provider> {
512 login(user: GetProviderRealUser<Provider>, options?: OATLoginOptions): Promise<ClientRequestData>;
513 }
514 /**
515 * Shape of OAT guard config.
516 */
517 export type OATGuardConfig<Provider extends keyof ProvidersList> = {
518 /**
519 * Driver name is always constant
520 */
521 driver: 'oat';
522 /**
523 * Provider for managing tokens
524 */
525 tokenProvider: DatabaseTokenProviderConfig | RedisTokenProviderConfig;
526 /**
527 * User provider
528 */
529 provider: ProvidersList[Provider]['config'];
530 };
531 /**
532 * List of providers mappings used by the app. Using declaration
533 * merging, one must extend this interface.
534 *
535 * MUST BE SET IN THE USER LAND.
536 *
537 * Example:
538 *
539 * lucid: {
540 * config: LucidProviderConfig<any>,
541 * implementation: LucidProviderContract<any>,
542 * }
543 *
544 */
545 export interface ProvidersList {
546 }
547 /**
548 * List of guards mappings used by the app. Using declaration
549 * merging, one must extend this interface.
550 *
551 * MUST BE SET IN THE USER LAND.
552 *
553 * Example:
554 *
555 * session: {
556 * config: SessionGuardConfig<'lucid'>,
557 * implementation: SessionGuardContract<'lucid'>,
558 * client: SessionClientContract<'lucid'>,
559 * }
560 *
561 */
562 export interface GuardsList {
563 }
564 /**
565 * Shape of config accepted by the Auth module. It relies on the
566 * [[GuardsList]] interface
567 */
568 export type AuthConfig = {
569 guard: keyof GuardsList;
570 guards: {
571 [P in keyof GuardsList]: GuardsList[P]['config'];
572 };
573 };
574 /**
575 * Instance of the auth contract. The `use` method can be used to obtain
576 * an instance of a given guard mapping for a single HTTP request
577 */
578 export interface AuthContract extends GuardContract<keyof ProvidersList, keyof GuardsList> {
579 /**
580 * The default guard for the current request
581 */
582 defaultGuard: string;
583 /**
584 * Use a given guard
585 */
586 use(): GuardContract<keyof ProvidersList, keyof GuardsList>;
587 use<K extends keyof GuardsList>(guard: K): GuardsList[K]['implementation'];
588 }
589 /**
590 * Shape of the callback accepted to add new user providers
591 */
592 export type ExtendProviderCallback = (auth: AuthManagerContract, mapping: string, config: any) => UserProviderContract<any>;
593 /**
594 * Shape of the callback accepted to add new guards
595 */
596 export type ExtendGuardCallback = (auth: AuthManagerContract, mapping: string, config: any, provider: UserProviderContract<any>, ctx: HttpContextContract) => GuardContract<keyof ProvidersList, keyof GuardsList>;
597 /**
598 * Shape of the callback accepted to add custom testing
599 * clients
600 */
601 export type ExtendClientCallback = (auth: AuthManagerContract, mapping: string, config: any, provider: UserProviderContract<any>) => GuardClientContract<keyof ProvidersList>;
602 /**
603 * Shape of the auth manager to register custom drivers and providers and
604 * make instances of them
605 */
606 export interface AuthManagerContract {
607 application: ApplicationContract;
608 /**
609 * The default guard
610 */
611 defaultGuard: string;
612 /**
613 * Returns the instance of [[AuthContract]] for a given HTTP request
614 */
615 getAuthForRequest(ctx: HttpContextContract): AuthContract;
616 /**
617 * Make instance of a mapping
618 */
619 makeMapping(ctx: HttpContextContract, mapping: string): GuardContract<keyof ProvidersList, keyof GuardsList>;
620 makeMapping<K extends keyof GuardsList>(ctx: HttpContextContract, mapping: K): GuardsList[K]['implementation'];
621 /**
622 * Returns an instance of the auth client for a given
623 * mapping
624 */
625 client(mapping: string): GuardClientContract<keyof ProvidersList>;
626 /**
627 * Extend by adding custom providers, guards and client
628 */
629 extend(type: 'provider', provider: string, callback: ExtendProviderCallback): void;
630 extend(type: 'guard', guard: string, callback: ExtendGuardCallback): void;
631 extend(type: 'client', guard: string, callback: ExtendClientCallback): void;
632 }
633 const AuthManager: AuthManagerContract;
634 export default AuthManager;
635}