UNPKG

20.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 export interface GuardContract<Provider extends keyof ProvidersList, Guard extends keyof GuardsList> {
234 name: Guard;
235 /**
236 * Reference to the guard config
237 */
238 config: GuardsList[Guard]['config'];
239 /**
240 * Reference to the logged in user.
241 */
242 user?: GetProviderRealUser<Provider>;
243 /**
244 * Find if the user has been logged out in the current request
245 */
246 isLoggedOut: boolean;
247 /**
248 * A boolean to know if user is a guest or not. It is
249 * always opposite of [[isLoggedIn]]
250 */
251 isGuest: boolean;
252 /**
253 * A boolean to know if user is logged in or not
254 */
255 isLoggedIn: boolean;
256 /**
257 * A boolean to know if user is retrieved by authenticating
258 * the current request or not.
259 */
260 isAuthenticated: boolean;
261 /**
262 * Whether or not the authentication has been attempted
263 * for the current request
264 */
265 authenticationAttempted: boolean;
266 /**
267 * Reference to the provider for looking up the user
268 */
269 provider: ProvidersList[Provider]['implementation'];
270 /**
271 * Verify user credentials.
272 */
273 verifyCredentials(uid: string, password: string): Promise<GetProviderRealUser<Provider>>;
274 /**
275 * Attempt to verify user credentials and perform login
276 */
277 attempt(uid: string, password: string, ...args: any[]): Promise<any>;
278 /**
279 * Login a user without any verification
280 */
281 login(user: GetProviderRealUser<Provider>, ...args: any[]): Promise<any>;
282 /**
283 * Login a user using their id
284 */
285 loginViaId(id: string | number, ...args: any[]): Promise<any>;
286 /**
287 * Attempts to authenticate the user for the current HTTP request. An exception
288 * is raised when unable to do so
289 */
290 authenticate(): Promise<GetProviderRealUser<Provider>>;
291 /**
292 * Attempts to authenticate the user for the current HTTP request and supresses
293 * exceptions raised by the [[authenticate]] method and returns a boolean
294 */
295 check(): Promise<boolean>;
296 /**
297 * Logout user
298 */
299 logout(...args: any[]): Promise<void>;
300 /**
301 * Serialize guard to JSON
302 */
303 toJSON(): any;
304 }
305 /**
306 * Shape of data emitted by the login event
307 */
308 export type SessionLoginEventData<Provider extends keyof ProvidersList> = {
309 name: string;
310 user: GetProviderRealUser<Provider>;
311 ctx: HttpContextContract;
312 token: string | null;
313 };
314 /**
315 * Shape of data emitted by the authenticate event
316 */
317 export type SessionAuthenticateEventData<Provider extends keyof ProvidersList> = {
318 name: string;
319 user: GetProviderRealUser<Provider>;
320 ctx: HttpContextContract;
321 viaRemember: boolean;
322 };
323 /**
324 * Shape of the session guard
325 */
326 export interface SessionGuardContract<Provider extends keyof ProvidersList, Name extends keyof GuardsList> extends GuardContract<Provider, Name> {
327 /**
328 * A boolean to know if user is loggedin via remember me token or not.
329 */
330 viaRemember: boolean;
331 /**
332 * Attempt to verify user credentials and perform login
333 */
334 attempt(uid: string, password: string, remember?: boolean): Promise<any>;
335 /**
336 * Login a user without any verification
337 */
338 login(user: GetProviderRealUser<Provider>, remember?: boolean): Promise<any>;
339 /**
340 * Login a user using their id
341 */
342 loginViaId(id: string | number, remember?: boolean): Promise<any>;
343 /**
344 * Logout user
345 */
346 logout(renewRememberToken?: boolean): Promise<void>;
347 }
348 /**
349 * Shape of session driver config.
350 */
351 export type SessionGuardConfig<Provider extends keyof ProvidersList> = {
352 driver: 'session';
353 provider: ProvidersList[Provider]['config'];
354 };
355 /**
356 * Shape of data emitted by the authenticate event
357 */
358 export type BasicAuthAuthenticateEventData<Provider extends keyof ProvidersList> = {
359 name: string;
360 user: GetProviderRealUser<Provider>;
361 ctx: HttpContextContract;
362 };
363 /**
364 * Shape of the basic auth guard
365 */
366 export interface BasicAuthGuardContract<Provider extends keyof ProvidersList, Name extends keyof GuardsList> extends Omit<GuardContract<Provider, Name>, 'attempt' | 'login' | 'loginViaId' | 'logout'> {
367 }
368 /**
369 * Shape of basic auth guard config.
370 */
371 export type BasicAuthGuardConfig<Provider extends keyof ProvidersList> = {
372 driver: 'basic';
373 realm?: string;
374 provider: ProvidersList[Provider]['config'];
375 };
376 /**
377 * Opaque token is generated during the login call by the OpaqueTokensGuard
378 */
379 export interface OpaqueTokenContract<User extends any> {
380 /**
381 * Always a bearer token
382 */
383 type: 'bearer';
384 /**
385 * The user for which the token was generated
386 */
387 user: User;
388 /**
389 * Date/time when the token will be expired
390 */
391 expiresAt?: DateTime;
392 /**
393 * Time in seconds until the token is valid
394 */
395 expiresIn?: number;
396 /**
397 * Any meta-data attached with the token
398 */
399 meta: any;
400 /**
401 * Token name
402 */
403 name: string;
404 /**
405 * Token public value
406 */
407 token: string;
408 /**
409 * Token hash (persisted to the db as well)
410 */
411 tokenHash: string;
412 /**
413 * Serialize token
414 */
415 toJSON(): {
416 type: 'bearer';
417 token: string;
418 expires_at?: string;
419 expires_in?: number;
420 };
421 }
422 /**
423 * Login options
424 */
425 export type OATLoginOptions = {
426 name?: string;
427 expiresIn?: number | string;
428 } & {
429 [key: string]: any;
430 };
431 /**
432 * Shape of data emitted by the login event
433 */
434 export type OATLoginEventData<Provider extends keyof ProvidersList> = {
435 name: string;
436 user: GetProviderRealUser<Provider>;
437 ctx: HttpContextContract;
438 token: OpaqueTokenContract<GetProviderRealUser<Provider>>;
439 };
440 /**
441 * Shape of the data emitted by the authenticate event
442 */
443 export type OATAuthenticateEventData<Provider extends keyof ProvidersList> = {
444 name: string;
445 user: GetProviderRealUser<Provider>;
446 ctx: HttpContextContract;
447 token: ProviderTokenContract;
448 };
449 /**
450 * Shape of the OAT guard
451 */
452 export interface OATGuardContract<Provider extends keyof ProvidersList, Name extends keyof GuardsList> extends GuardContract<Provider, Name> {
453 token?: ProviderTokenContract;
454 tokenProvider: TokenProviderContract;
455 /**
456 * Attempt to verify user credentials and perform login
457 */
458 attempt(uid: string, password: string, options?: OATLoginOptions): Promise<OpaqueTokenContract<GetProviderRealUser<Provider>>>;
459 /**
460 * Login a user without any verification
461 */
462 login(user: GetProviderRealUser<Provider>, options?: OATLoginOptions): Promise<OpaqueTokenContract<GetProviderRealUser<Provider>>>;
463 /**
464 * Generate token for a user without any verification
465 */
466 generate(user: GetProviderRealUser<Provider>, options?: OATLoginOptions): Promise<OpaqueTokenContract<GetProviderRealUser<Provider>>>;
467 /**
468 * Alias for logout
469 */
470 revoke(): Promise<void>;
471 /**
472 * Login a user using their id
473 */
474 loginViaId(id: string | number, options?: OATLoginOptions): Promise<OpaqueTokenContract<GetProviderRealUser<Provider>>>;
475 }
476 /**
477 * Shape of OAT guard config.
478 */
479 export type OATGuardConfig<Provider extends keyof ProvidersList> = {
480 /**
481 * Driver name is always constant
482 */
483 driver: 'oat';
484 /**
485 * Provider for managing tokens
486 */
487 tokenProvider: DatabaseTokenProviderConfig | RedisTokenProviderConfig;
488 /**
489 * User provider
490 */
491 provider: ProvidersList[Provider]['config'];
492 };
493 /**
494 * List of providers mappings used by the app. Using declaration
495 * merging, one must extend this interface.
496 *
497 * MUST BE SET IN THE USER LAND.
498 *
499 * Example:
500 *
501 * lucid: {
502 * config: LucidProviderConfig<any>,
503 * implementation: LucidProviderContract<any>,
504 * }
505 *
506 */
507 export interface ProvidersList {
508 }
509 /**
510 * List of guards mappings used by the app. Using declaration
511 * merging, one must extend this interface.
512 *
513 * MUST BE SET IN THE USER LAND.
514 *
515 * Example:
516 *
517 * session: {
518 * config: SessionGuardConfig<'lucid'>,
519 * implementation: SessionGuardContract<'lucid'>,
520 * }
521 *
522 */
523 export interface GuardsList {
524 }
525 /**
526 * Shape of config accepted by the Auth module. It relies on the
527 * [[GuardsList]] interface
528 */
529 export type AuthConfig = {
530 guard: keyof GuardsList;
531 guards: {
532 [P in keyof GuardsList]: GuardsList[P]['config'];
533 };
534 };
535 /**
536 * Instance of the auth contract. The `use` method can be used to obtain
537 * an instance of a given guard mapping for a single HTTP request
538 */
539 export interface AuthContract extends GuardContract<keyof ProvidersList, keyof GuardsList> {
540 /**
541 * The default guard for the current request
542 */
543 defaultGuard: string;
544 /**
545 * Use a given guard
546 */
547 use(): GuardContract<keyof ProvidersList, keyof GuardsList>;
548 use<K extends keyof GuardsList>(guard: K): GuardsList[K]['implementation'];
549 }
550 /**
551 * Shape of the callback accepted to add new user providers
552 */
553 export type ExtendProviderCallback = (auth: AuthManagerContract, mapping: string, config: any) => UserProviderContract<any>;
554 /**
555 * Shape of the callback accepted to add new guards
556 */
557 export type ExtendGuardCallback = (auth: AuthManagerContract, mapping: string, config: any, provider: UserProviderContract<any>, ctx: HttpContextContract) => GuardContract<keyof ProvidersList, keyof GuardsList>;
558 /**
559 * Shape of the auth manager to register custom drivers and providers and
560 * make instances of them
561 */
562 export interface AuthManagerContract {
563 application: ApplicationContract;
564 /**
565 * The default guard
566 */
567 defaultGuard: string;
568 /**
569 * Returns the instance of [[AuthContract]] for a given HTTP request
570 */
571 getAuthForRequest(ctx: HttpContextContract): AuthContract;
572 /**
573 * Make instance of a mapping
574 */
575 makeMapping(ctx: HttpContextContract, mapping: string): GuardContract<keyof ProvidersList, keyof GuardsList>;
576 makeMapping<K extends keyof GuardsList>(ctx: HttpContextContract, mapping: K): GuardsList[K]['implementation'];
577 /**
578 * Extend by adding custom providers and guards
579 */
580 extend(type: 'provider', provider: string, callback: ExtendProviderCallback): void;
581 extend(type: 'guard', guard: string, callback: ExtendGuardCallback): void;
582 }
583 const AuthManager: AuthManagerContract;
584 export default AuthManager;
585}