@adonisjs/auth 8.2.3 → 9.0.0-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/README.md +19 -40
- package/build/configure.d.ts +5 -0
- package/build/configure.js +55 -0
- package/build/factories/database_token_factory.d.ts +36 -0
- package/build/factories/database_token_factory.js +54 -0
- package/build/factories/database_user_provider.d.ts +14 -0
- package/build/factories/database_user_provider.js +27 -0
- package/build/factories/lucid_user_provider.d.ts +28 -0
- package/build/factories/lucid_user_provider.js +68 -0
- package/build/factories/main.d.ts +4 -0
- package/build/factories/main.js +12 -0
- package/build/factories/session_guard_factory.d.ts +13 -0
- package/build/factories/session_guard_factory.js +24 -0
- package/build/index.d.ts +7 -0
- package/build/index.js +15 -0
- package/build/providers/auth_provider.d.ts +12 -0
- package/build/providers/auth_provider.js +27 -0
- package/build/services/auth.d.ts +3 -0
- package/build/services/auth.js +17 -0
- package/build/src/auth/auth_manager.d.ts +22 -0
- package/build/src/auth/auth_manager.js +34 -0
- package/build/src/auth/authenticator.d.ts +56 -0
- package/build/src/auth/authenticator.js +122 -0
- package/build/src/auth/debug.d.ts +3 -0
- package/build/{adonis-typings/container.js → src/auth/debug.js} +3 -1
- package/build/src/auth/define_config.d.ts +30 -0
- package/build/src/auth/define_config.js +54 -0
- package/build/src/auth/errors.d.ts +82 -0
- package/build/src/auth/errors.js +181 -0
- package/build/src/auth/middleware/auth_middleware.d.ts +13 -0
- package/build/src/auth/middleware/auth_middleware.js +6 -0
- package/build/src/auth/middleware/initialize_auth_middleware.d.ts +18 -0
- package/build/src/auth/middleware/initialize_auth_middleware.js +25 -0
- package/build/src/auth/symbols.d.ts +9 -0
- package/build/src/auth/symbols.js +17 -0
- package/build/src/auth/types.d.ts +75 -0
- package/build/{adonis-typings/context.js → src/auth/types.js} +2 -1
- package/build/src/auth/user_providers/main.d.ts +15 -0
- package/build/src/auth/user_providers/main.js +22 -0
- package/build/src/core/guard_user.d.ts +26 -0
- package/build/src/core/guard_user.js +29 -0
- package/build/src/core/token.d.ts +89 -0
- package/build/src/core/token.js +114 -0
- package/build/src/core/token_providers/database.d.ts +77 -0
- package/build/src/core/token_providers/database.js +113 -0
- package/build/src/core/types.d.ts +178 -0
- package/build/{adonis-typings/auth.js → src/core/types.js} +2 -1
- package/build/src/core/user_providers/database.d.ts +78 -0
- package/build/src/core/user_providers/database.js +117 -0
- package/build/src/core/user_providers/lucid.d.ts +61 -0
- package/build/src/core/user_providers/lucid.js +122 -0
- package/build/src/guards/session/define_config.d.ts +23 -0
- package/build/src/guards/session/define_config.js +56 -0
- package/build/src/guards/session/guard.d.ts +112 -0
- package/build/src/guards/session/guard.js +454 -0
- package/build/src/guards/session/main.d.ts +3 -0
- package/build/src/guards/session/main.js +11 -0
- package/build/src/guards/session/token.d.ts +57 -0
- package/build/src/guards/session/token.js +58 -0
- package/build/src/guards/session/token_providers/main.d.ts +33 -0
- package/build/src/guards/session/token_providers/main.js +42 -0
- package/build/src/guards/session/types.d.ts +96 -0
- package/build/{adonis-typings/events.js → src/guards/session/types.js} +2 -1
- package/build/stubs/config.stub +35 -0
- package/build/stubs/main.d.ts +1 -0
- package/build/{adonis-typings/tests.js → stubs/main.js} +2 -3
- package/package.json +99 -91
- package/build/adonis-typings/auth.d.ts +0 -635
- package/build/adonis-typings/container.d.ts +0 -6
- package/build/adonis-typings/context.d.ts +0 -6
- package/build/adonis-typings/events.d.ts +0 -10
- package/build/adonis-typings/index.d.ts +0 -5
- package/build/adonis-typings/index.js +0 -13
- package/build/adonis-typings/tests.d.ts +0 -23
- package/build/instructions.js +0 -338
- package/build/providers/AuthProvider.d.ts +0 -30
- package/build/providers/AuthProvider.js +0 -69
- package/build/src/Auth/index.d.ts +0 -97
- package/build/src/Auth/index.js +0 -155
- package/build/src/AuthManager/index.d.ts +0 -117
- package/build/src/AuthManager/index.js +0 -262
- package/build/src/Bindings/Tests.d.ts +0 -6
- package/build/src/Bindings/Tests.js +0 -69
- package/build/src/Clients/Oat/index.d.ts +0 -50
- package/build/src/Clients/Oat/index.js +0 -123
- package/build/src/Clients/Session/index.d.ts +0 -34
- package/build/src/Clients/Session/index.js +0 -72
- package/build/src/Exceptions/AuthenticationException.d.ts +0 -47
- package/build/src/Exceptions/AuthenticationException.js +0 -142
- package/build/src/Exceptions/InvalidCredentialsException.d.ts +0 -34
- package/build/src/Exceptions/InvalidCredentialsException.js +0 -112
- package/build/src/Guards/Base/index.d.ts +0 -75
- package/build/src/Guards/Base/index.js +0 -138
- package/build/src/Guards/BasicAuth/index.d.ts +0 -67
- package/build/src/Guards/BasicAuth/index.js +0 -181
- package/build/src/Guards/Oat/index.d.ts +0 -149
- package/build/src/Guards/Oat/index.js +0 -347
- package/build/src/Guards/Session/index.d.ts +0 -127
- package/build/src/Guards/Session/index.js +0 -338
- package/build/src/TokenProviders/Database/index.d.ts +0 -43
- package/build/src/TokenProviders/Database/index.js +0 -126
- package/build/src/TokenProviders/Redis/index.d.ts +0 -44
- package/build/src/TokenProviders/Redis/index.js +0 -129
- package/build/src/Tokens/OpaqueToken/index.d.ts +0 -46
- package/build/src/Tokens/OpaqueToken/index.js +0 -43
- package/build/src/Tokens/ProviderToken/index.d.ts +0 -23
- package/build/src/Tokens/ProviderToken/index.js +0 -27
- package/build/src/UserProviders/Database/User.d.ts +0 -28
- package/build/src/UserProviders/Database/User.js +0 -74
- package/build/src/UserProviders/Database/index.d.ts +0 -75
- package/build/src/UserProviders/Database/index.js +0 -141
- package/build/src/UserProviders/Lucid/User.d.ts +0 -28
- package/build/src/UserProviders/Lucid/User.js +0 -74
- package/build/src/UserProviders/Lucid/index.d.ts +0 -72
- package/build/src/UserProviders/Lucid/index.js +0 -146
- package/build/standalone.d.ts +0 -1
- package/build/standalone.js +0 -13
- package/build/templates/config/auth.txt +0 -34
- package/build/templates/config/partials/api-guard.txt +0 -22
- package/build/templates/config/partials/basic-guard.txt +0 -19
- package/build/templates/config/partials/tokens-provider-database.txt +0 -19
- package/build/templates/config/partials/tokens-provider-redis.txt +0 -22
- package/build/templates/config/partials/user-provider-database.txt +0 -43
- package/build/templates/config/partials/user-provider-lucid.txt +0 -45
- package/build/templates/config/partials/web-guard.txt +0 -17
- package/build/templates/contract/auth.txt +0 -55
- package/build/templates/contract/partials/api-guard.txt +0 -14
- package/build/templates/contract/partials/basic-guard.txt +0 -14
- package/build/templates/contract/partials/user-provider-database.txt +0 -16
- package/build/templates/contract/partials/user-provider-lucid.txt +0 -16
- package/build/templates/contract/partials/web-guard.txt +0 -14
- package/build/templates/middleware/Auth.txt +0 -76
- package/build/templates/middleware/SilentAuth.txt +0 -21
- package/build/templates/migrations/api_tokens.txt +0 -25
- package/build/templates/migrations/auth.txt +0 -24
- package/build/templates/model.txt +0 -30
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @adonisjs/auth
|
|
3
|
+
*
|
|
4
|
+
* (c) AdonisJS
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import debug from './debug.js';
|
|
10
|
+
import { AuthenticationException } from './errors.js';
|
|
11
|
+
/**
|
|
12
|
+
* Authenticator is an HTTP request specific implementation for using
|
|
13
|
+
* guards to login users and authenticate requests.
|
|
14
|
+
*/
|
|
15
|
+
export class Authenticator {
|
|
16
|
+
/**
|
|
17
|
+
* Name of the guard using which the request has
|
|
18
|
+
* been authenticated
|
|
19
|
+
*/
|
|
20
|
+
#authenticatedViaGuard;
|
|
21
|
+
/**
|
|
22
|
+
* Reference to HTTP context
|
|
23
|
+
*/
|
|
24
|
+
#ctx;
|
|
25
|
+
/**
|
|
26
|
+
* Registered guards
|
|
27
|
+
*/
|
|
28
|
+
#config;
|
|
29
|
+
/**
|
|
30
|
+
* Cache of guards created during the HTTP request
|
|
31
|
+
*/
|
|
32
|
+
#guardsCache = {};
|
|
33
|
+
/**
|
|
34
|
+
* Name of the default guard
|
|
35
|
+
*/
|
|
36
|
+
get defaultGuard() {
|
|
37
|
+
return this.#config.default;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Reference to the guard using which the current
|
|
41
|
+
* request has been authenticated.
|
|
42
|
+
*/
|
|
43
|
+
get authenticatedViaGuard() {
|
|
44
|
+
return this.#authenticatedViaGuard;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A boolean to know if the current request has
|
|
48
|
+
* been authenticated
|
|
49
|
+
*/
|
|
50
|
+
get isAuthenticated() {
|
|
51
|
+
return this.use(this.#authenticatedViaGuard || this.defaultGuard).isAuthenticated;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Reference to the currently authenticated user
|
|
55
|
+
*/
|
|
56
|
+
get user() {
|
|
57
|
+
return this.use(this.#authenticatedViaGuard || this.defaultGuard).user;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Whether or not the authentication has been attempted
|
|
61
|
+
* during the current request
|
|
62
|
+
*/
|
|
63
|
+
get authenticationAttempted() {
|
|
64
|
+
return this.use(this.#authenticatedViaGuard || this.defaultGuard).authenticationAttempted;
|
|
65
|
+
}
|
|
66
|
+
constructor(ctx, config) {
|
|
67
|
+
this.#ctx = ctx;
|
|
68
|
+
this.#config = config;
|
|
69
|
+
debug('creating authenticator. config %O', this.#config);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Returns an instance of a known guard. Guards instances are
|
|
73
|
+
* cached during the lifecycle of an HTTP request.
|
|
74
|
+
*/
|
|
75
|
+
use(guard) {
|
|
76
|
+
const guardToUse = guard || this.#config.default;
|
|
77
|
+
/**
|
|
78
|
+
* Use cached copy if exists
|
|
79
|
+
*/
|
|
80
|
+
const cachedGuard = this.#guardsCache[guardToUse];
|
|
81
|
+
if (cachedGuard) {
|
|
82
|
+
debug('using guard from cache. name: "%s"', guardToUse);
|
|
83
|
+
return cachedGuard;
|
|
84
|
+
}
|
|
85
|
+
const guardFactory = this.#config.guards[guardToUse];
|
|
86
|
+
/**
|
|
87
|
+
* Construct guard and cache it
|
|
88
|
+
*/
|
|
89
|
+
debug('creating guard. name: "%s"', guardToUse);
|
|
90
|
+
const guardInstance = guardFactory(this.#ctx);
|
|
91
|
+
this.#guardsCache[guardToUse] = guardInstance;
|
|
92
|
+
return guardInstance;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Authenticate the request using all of the mentioned
|
|
96
|
+
* guards or the default guard.
|
|
97
|
+
*
|
|
98
|
+
* The authentication process will stop after any of the
|
|
99
|
+
* mentioned guards is able to authenticate the request
|
|
100
|
+
* successfully.
|
|
101
|
+
*
|
|
102
|
+
* Otherwise, "AuthenticationException" will be raised.
|
|
103
|
+
*/
|
|
104
|
+
async authenticateUsing(guards, options) {
|
|
105
|
+
const guardsToUse = guards || [this.defaultGuard];
|
|
106
|
+
let lastUsedGuardDriver;
|
|
107
|
+
for (let guardName of guardsToUse) {
|
|
108
|
+
debug('attempting to authenticate using guard "%s"', guardName);
|
|
109
|
+
const guard = this.use(guardName);
|
|
110
|
+
lastUsedGuardDriver = guard.driverName;
|
|
111
|
+
if (await guard.check()) {
|
|
112
|
+
this.#authenticatedViaGuard = guardName;
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
throw new AuthenticationException('Unauthorized access', {
|
|
117
|
+
code: 'E_UNAUTHORIZED_ACCESS',
|
|
118
|
+
guardDriverName: lastUsedGuardDriver,
|
|
119
|
+
redirectTo: options?.redirectTo,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* @adonisjs/auth
|
|
3
3
|
*
|
|
4
|
-
* (c)
|
|
4
|
+
* (c) AdonisJS
|
|
5
5
|
*
|
|
6
6
|
* For the full copyright and license information, please view the LICENSE
|
|
7
7
|
* file that was distributed with this source code.
|
|
8
8
|
*/
|
|
9
|
+
import { debuglog } from 'node:util';
|
|
10
|
+
export default debuglog('adonisjs:auth');
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ConfigProvider } from '@adonisjs/core/types';
|
|
2
|
+
import type { GuardConfigProvider, GuardFactory } from './types.js';
|
|
3
|
+
import type { LucidUserProvider, DatabaseUserProvider } from './user_providers/main.js';
|
|
4
|
+
import type { LucidAuthenticatable, LucidUserProviderOptions, DatabaseUserProviderOptions } from '../core/types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Config resolved by the "defineConfig" method
|
|
7
|
+
*/
|
|
8
|
+
export type ResolvedAuthConfig<KnownGuards extends Record<string, GuardFactory | GuardConfigProvider<GuardFactory>>> = {
|
|
9
|
+
default: keyof KnownGuards;
|
|
10
|
+
guards: {
|
|
11
|
+
[K in keyof KnownGuards]: KnownGuards[K] extends GuardConfigProvider<infer A> ? A : KnownGuards[K];
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Define configuration for the auth package. The function returns
|
|
16
|
+
* a config provider that is invoked inside the auth service
|
|
17
|
+
* provider
|
|
18
|
+
*/
|
|
19
|
+
export declare function defineConfig<KnownGuards extends Record<string, GuardFactory | GuardConfigProvider<GuardFactory>>>(config: {
|
|
20
|
+
default: keyof KnownGuards;
|
|
21
|
+
guards: KnownGuards;
|
|
22
|
+
}): ConfigProvider<ResolvedAuthConfig<KnownGuards>>;
|
|
23
|
+
/**
|
|
24
|
+
* Providers helper to configure user providers for
|
|
25
|
+
* finding users for authentication
|
|
26
|
+
*/
|
|
27
|
+
export declare const providers: {
|
|
28
|
+
db: <RealUser extends Record<string, any>>(config: DatabaseUserProviderOptions<RealUser>) => ConfigProvider<DatabaseUserProvider<RealUser>>;
|
|
29
|
+
lucid: <RealUser extends LucidAuthenticatable>(config: LucidUserProviderOptions<RealUser>) => ConfigProvider<LucidUserProvider<RealUser>>;
|
|
30
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @adonisjs/auth
|
|
3
|
+
*
|
|
4
|
+
* (c) AdonisJS
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
/// <reference types="@adonisjs/lucid/database_provider" />
|
|
10
|
+
import { configProvider } from '@adonisjs/core';
|
|
11
|
+
/**
|
|
12
|
+
* Define configuration for the auth package. The function returns
|
|
13
|
+
* a config provider that is invoked inside the auth service
|
|
14
|
+
* provider
|
|
15
|
+
*/
|
|
16
|
+
export function defineConfig(config) {
|
|
17
|
+
return configProvider.create(async (app) => {
|
|
18
|
+
const guardsList = Object.keys(config.guards);
|
|
19
|
+
const guards = {};
|
|
20
|
+
for (let guardName of guardsList) {
|
|
21
|
+
const guard = config.guards[guardName];
|
|
22
|
+
if (typeof guard === 'function') {
|
|
23
|
+
guards[guardName] = guard;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
guards[guardName] = await guard.resolver(guardName, app);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
default: config.default,
|
|
31
|
+
guards: guards,
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Providers helper to configure user providers for
|
|
37
|
+
* finding users for authentication
|
|
38
|
+
*/
|
|
39
|
+
export const providers = {
|
|
40
|
+
db(config) {
|
|
41
|
+
return configProvider.create(async (app) => {
|
|
42
|
+
const db = await app.container.make('lucid.db');
|
|
43
|
+
const hasher = await app.container.make('hash');
|
|
44
|
+
const { DatabaseUserProvider } = await import('./user_providers/main.js');
|
|
45
|
+
return new DatabaseUserProvider(db, hasher.use(), config);
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
lucid(config) {
|
|
49
|
+
return configProvider.create(async () => {
|
|
50
|
+
const { LucidUserProvider } = await import('./user_providers/main.js');
|
|
51
|
+
return new LucidUserProvider(config);
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Exception } from '@poppinss/utils';
|
|
2
|
+
import { HttpContext } from '@adonisjs/core/http';
|
|
3
|
+
/**
|
|
4
|
+
* Authentication exception is raised when an attempt is
|
|
5
|
+
* made to authenticate an HTTP request
|
|
6
|
+
*/
|
|
7
|
+
export declare class AuthenticationException extends Exception {
|
|
8
|
+
/**
|
|
9
|
+
* Raises authentication exception when session guard
|
|
10
|
+
* is unable to authenticate the request
|
|
11
|
+
*/
|
|
12
|
+
static E_INVALID_AUTH_SESSION(): AuthenticationException;
|
|
13
|
+
guardDriverName: string;
|
|
14
|
+
redirectTo?: string;
|
|
15
|
+
identifier: string;
|
|
16
|
+
constructor(message: string, options: ErrorOptions & {
|
|
17
|
+
guardDriverName: string;
|
|
18
|
+
redirectTo?: string;
|
|
19
|
+
code?: string;
|
|
20
|
+
status?: number;
|
|
21
|
+
});
|
|
22
|
+
/**
|
|
23
|
+
* Returns the message to be sent in the HTTP response.
|
|
24
|
+
* Feel free to override this method and return a custom
|
|
25
|
+
* response.
|
|
26
|
+
*/
|
|
27
|
+
getResponseMessage(error: AuthenticationException, ctx: HttpContext): string;
|
|
28
|
+
/**
|
|
29
|
+
* A collection of authentication exception
|
|
30
|
+
* renderers to render the exception to a
|
|
31
|
+
* response.
|
|
32
|
+
*
|
|
33
|
+
* The collection is a key-value pair, where the
|
|
34
|
+
* key is the guard driver name and value is
|
|
35
|
+
* a factory function to respond to the
|
|
36
|
+
* request.
|
|
37
|
+
*/
|
|
38
|
+
renderers: Record<string, (message: string, error: AuthenticationException, ctx: HttpContext) => Promise<void> | void>;
|
|
39
|
+
/**
|
|
40
|
+
* Self handles the auth exception and converts it to an
|
|
41
|
+
* HTTP response
|
|
42
|
+
*/
|
|
43
|
+
handle(error: AuthenticationException, ctx: HttpContext): Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Invalid credentials exception is raised when unable
|
|
47
|
+
* to verify user credentials during login
|
|
48
|
+
*/
|
|
49
|
+
export declare class InvalidCredentialsException extends Exception {
|
|
50
|
+
static message: string;
|
|
51
|
+
static code: string;
|
|
52
|
+
static E_INVALID_CREDENTIALS(guardDriverName: string): InvalidCredentialsException;
|
|
53
|
+
guardDriverName: string;
|
|
54
|
+
identifier: string;
|
|
55
|
+
constructor(message: string, options: ErrorOptions & {
|
|
56
|
+
guardDriverName: string;
|
|
57
|
+
code?: string;
|
|
58
|
+
status?: number;
|
|
59
|
+
});
|
|
60
|
+
/**
|
|
61
|
+
* Returns the message to be sent in the HTTP response.
|
|
62
|
+
* Feel free to override this method and return a custom
|
|
63
|
+
* response.
|
|
64
|
+
*/
|
|
65
|
+
getResponseMessage(error: InvalidCredentialsException, ctx: HttpContext): string;
|
|
66
|
+
/**
|
|
67
|
+
* A collection of authentication exception
|
|
68
|
+
* renderers to render the exception to a
|
|
69
|
+
* response.
|
|
70
|
+
*
|
|
71
|
+
* The collection is a key-value pair, where the
|
|
72
|
+
* key is the guard driver name and value is
|
|
73
|
+
* a factory function to respond to the
|
|
74
|
+
* request.
|
|
75
|
+
*/
|
|
76
|
+
renderers: Record<string, (message: string, error: InvalidCredentialsException, ctx: HttpContext) => Promise<void> | void>;
|
|
77
|
+
/**
|
|
78
|
+
* Self handles the auth exception and converts it to an
|
|
79
|
+
* HTTP response
|
|
80
|
+
*/
|
|
81
|
+
handle(error: InvalidCredentialsException, ctx: HttpContext): Promise<void>;
|
|
82
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @adonisjs/auth
|
|
3
|
+
*
|
|
4
|
+
* (c) AdonisJS
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import { Exception } from '@poppinss/utils';
|
|
10
|
+
/**
|
|
11
|
+
* Authentication exception is raised when an attempt is
|
|
12
|
+
* made to authenticate an HTTP request
|
|
13
|
+
*/
|
|
14
|
+
export class AuthenticationException extends Exception {
|
|
15
|
+
/**
|
|
16
|
+
* Raises authentication exception when session guard
|
|
17
|
+
* is unable to authenticate the request
|
|
18
|
+
*/
|
|
19
|
+
static E_INVALID_AUTH_SESSION() {
|
|
20
|
+
return new AuthenticationException('Invalid or expired authentication session', {
|
|
21
|
+
code: 'E_INVALID_AUTH_SESSION',
|
|
22
|
+
status: 401,
|
|
23
|
+
guardDriverName: 'session',
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
guardDriverName;
|
|
27
|
+
redirectTo;
|
|
28
|
+
identifier = 'auth.authenticate';
|
|
29
|
+
constructor(message, options) {
|
|
30
|
+
super(message, options);
|
|
31
|
+
this.guardDriverName = options.guardDriverName;
|
|
32
|
+
this.redirectTo = options.redirectTo;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Returns the message to be sent in the HTTP response.
|
|
36
|
+
* Feel free to override this method and return a custom
|
|
37
|
+
* response.
|
|
38
|
+
*/
|
|
39
|
+
getResponseMessage(error, ctx) {
|
|
40
|
+
if ('i18n' in ctx) {
|
|
41
|
+
return ctx.i18n.t(error.identifier, {}, error.message);
|
|
42
|
+
}
|
|
43
|
+
return error.message;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A collection of authentication exception
|
|
47
|
+
* renderers to render the exception to a
|
|
48
|
+
* response.
|
|
49
|
+
*
|
|
50
|
+
* The collection is a key-value pair, where the
|
|
51
|
+
* key is the guard driver name and value is
|
|
52
|
+
* a factory function to respond to the
|
|
53
|
+
* request.
|
|
54
|
+
*/
|
|
55
|
+
renderers = {
|
|
56
|
+
session: (message, error, ctx) => {
|
|
57
|
+
switch (ctx.request.accepts(['html', 'application/vnd.api+json', 'json'])) {
|
|
58
|
+
case 'html':
|
|
59
|
+
case null:
|
|
60
|
+
ctx.session.flashExcept(['_csrf']);
|
|
61
|
+
ctx.session.flash({ errors: { [error.identifier]: [message] } });
|
|
62
|
+
ctx.response.redirect(error.redirectTo || '/', true);
|
|
63
|
+
break;
|
|
64
|
+
case 'json':
|
|
65
|
+
ctx.response.status(error.status).send({
|
|
66
|
+
errors: [
|
|
67
|
+
{
|
|
68
|
+
message,
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
});
|
|
72
|
+
break;
|
|
73
|
+
case 'application/vnd.api+json':
|
|
74
|
+
ctx.response.status(error.status).send({
|
|
75
|
+
errors: [
|
|
76
|
+
{
|
|
77
|
+
code: error.identifier,
|
|
78
|
+
title: message,
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
});
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Self handles the auth exception and converts it to an
|
|
88
|
+
* HTTP response
|
|
89
|
+
*/
|
|
90
|
+
async handle(error, ctx) {
|
|
91
|
+
const renderer = this.renderers[this.guardDriverName];
|
|
92
|
+
const message = error.getResponseMessage(error, ctx);
|
|
93
|
+
if (!renderer) {
|
|
94
|
+
return ctx.response.status(error.status).send(message);
|
|
95
|
+
}
|
|
96
|
+
return renderer(message, error, ctx);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Invalid credentials exception is raised when unable
|
|
101
|
+
* to verify user credentials during login
|
|
102
|
+
*/
|
|
103
|
+
export class InvalidCredentialsException extends Exception {
|
|
104
|
+
static message = 'Invalid credentials';
|
|
105
|
+
static code = 'E_INVALID_CREDENTIALS';
|
|
106
|
+
static E_INVALID_CREDENTIALS(guardDriverName) {
|
|
107
|
+
return new InvalidCredentialsException(InvalidCredentialsException.message, {
|
|
108
|
+
guardDriverName,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
guardDriverName;
|
|
112
|
+
identifier = 'auth.login';
|
|
113
|
+
constructor(message, options) {
|
|
114
|
+
super(message, options);
|
|
115
|
+
this.guardDriverName = options.guardDriverName;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Returns the message to be sent in the HTTP response.
|
|
119
|
+
* Feel free to override this method and return a custom
|
|
120
|
+
* response.
|
|
121
|
+
*/
|
|
122
|
+
getResponseMessage(error, ctx) {
|
|
123
|
+
if ('i18n' in ctx) {
|
|
124
|
+
return ctx.i18n.t(this.identifier, {}, error.message);
|
|
125
|
+
}
|
|
126
|
+
return error.message;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* A collection of authentication exception
|
|
130
|
+
* renderers to render the exception to a
|
|
131
|
+
* response.
|
|
132
|
+
*
|
|
133
|
+
* The collection is a key-value pair, where the
|
|
134
|
+
* key is the guard driver name and value is
|
|
135
|
+
* a factory function to respond to the
|
|
136
|
+
* request.
|
|
137
|
+
*/
|
|
138
|
+
renderers = {
|
|
139
|
+
session: (message, error, ctx) => {
|
|
140
|
+
switch (ctx.request.accepts(['html', 'application/vnd.api+json', 'json'])) {
|
|
141
|
+
case 'html':
|
|
142
|
+
case null:
|
|
143
|
+
ctx.session.flashExcept(['_csrf']);
|
|
144
|
+
ctx.session.flash({ errors: { [this.identifier]: [message] } });
|
|
145
|
+
ctx.response.redirect().withQs().back();
|
|
146
|
+
break;
|
|
147
|
+
case 'json':
|
|
148
|
+
ctx.response.status(error.status).send({
|
|
149
|
+
errors: [
|
|
150
|
+
{
|
|
151
|
+
message: message,
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
});
|
|
155
|
+
break;
|
|
156
|
+
case 'application/vnd.api+json':
|
|
157
|
+
ctx.response.status(error.status).send({
|
|
158
|
+
errors: [
|
|
159
|
+
{
|
|
160
|
+
code: this.identifier,
|
|
161
|
+
title: message,
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
});
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* Self handles the auth exception and converts it to an
|
|
171
|
+
* HTTP response
|
|
172
|
+
*/
|
|
173
|
+
async handle(error, ctx) {
|
|
174
|
+
const renderer = this.renderers[this.guardDriverName];
|
|
175
|
+
const message = this.getResponseMessage(error, ctx);
|
|
176
|
+
if (!renderer) {
|
|
177
|
+
return ctx.response.status(error.status).send(message);
|
|
178
|
+
}
|
|
179
|
+
return renderer(message, error, ctx);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { HttpContext } from '@adonisjs/core/http';
|
|
2
|
+
import type { NextFn } from '@adonisjs/core/types/http';
|
|
3
|
+
import type { Authenticators } from '@adonisjs/auth/types';
|
|
4
|
+
/**
|
|
5
|
+
* Options accepted by the middleware options
|
|
6
|
+
*/
|
|
7
|
+
export type AuthMiddlewareOptions = {
|
|
8
|
+
guards?: (keyof Authenticators)[];
|
|
9
|
+
redirectTo?: string;
|
|
10
|
+
};
|
|
11
|
+
export default class AuthMiddleware {
|
|
12
|
+
handle(ctx: HttpContext, next: NextFn, options?: AuthMiddlewareOptions): Promise<any>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import auth from '@adonisjs/auth/services/main';
|
|
2
|
+
import type { HttpContext } from '@adonisjs/core/http';
|
|
3
|
+
import type { NextFn } from '@adonisjs/core/types/http';
|
|
4
|
+
/**
|
|
5
|
+
* The "InitializeAuthMiddleware" is used to create a request
|
|
6
|
+
* specific authenticator instance for every HTTP request.
|
|
7
|
+
*
|
|
8
|
+
* This middleware does not protect routes from unauthenticated
|
|
9
|
+
* users. Please use the "auth" middleware for that.
|
|
10
|
+
*/
|
|
11
|
+
export default class InitializeAuthMiddleware {
|
|
12
|
+
handle(ctx: HttpContext, next: NextFn): Promise<any>;
|
|
13
|
+
}
|
|
14
|
+
declare module '@adonisjs/core/http' {
|
|
15
|
+
interface HttpContext {
|
|
16
|
+
auth: ReturnType<(typeof auth)['createAuthenticator']>;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/// <reference types="@adonisjs/core/providers/edge_provider" />
|
|
2
|
+
import auth from '@adonisjs/auth/services/main';
|
|
3
|
+
/**
|
|
4
|
+
* The "InitializeAuthMiddleware" is used to create a request
|
|
5
|
+
* specific authenticator instance for every HTTP request.
|
|
6
|
+
*
|
|
7
|
+
* This middleware does not protect routes from unauthenticated
|
|
8
|
+
* users. Please use the "auth" middleware for that.
|
|
9
|
+
*/
|
|
10
|
+
export default class InitializeAuthMiddleware {
|
|
11
|
+
async handle(ctx, next) {
|
|
12
|
+
/**
|
|
13
|
+
* Initialize the authenticator for the current HTTP
|
|
14
|
+
* request
|
|
15
|
+
*/
|
|
16
|
+
ctx.auth = auth.createAuthenticator(ctx);
|
|
17
|
+
/**
|
|
18
|
+
* Sharing authenticator with templates
|
|
19
|
+
*/
|
|
20
|
+
if ('view' in ctx) {
|
|
21
|
+
ctx.view.share({ auth: ctx.auth });
|
|
22
|
+
}
|
|
23
|
+
return next();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A symbol to identify the type of the real user for a given
|
|
3
|
+
* user provider
|
|
4
|
+
*/
|
|
5
|
+
export declare const PROVIDER_REAL_USER: unique symbol;
|
|
6
|
+
/**
|
|
7
|
+
* A symbol to identify the type for the events emitted by a guard
|
|
8
|
+
*/
|
|
9
|
+
export declare const GUARD_KNOWN_EVENTS: unique symbol;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @adonisjs/lucid
|
|
3
|
+
*
|
|
4
|
+
* (c) AdonisJS
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* A symbol to identify the type of the real user for a given
|
|
11
|
+
* user provider
|
|
12
|
+
*/
|
|
13
|
+
export const PROVIDER_REAL_USER = Symbol.for('PROVIDER_REAL_USER');
|
|
14
|
+
/**
|
|
15
|
+
* A symbol to identify the type for the events emitted by a guard
|
|
16
|
+
*/
|
|
17
|
+
export const GUARD_KNOWN_EVENTS = Symbol.for('GUARD_KNOWN_EVENTS');
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { HttpContext } from '@adonisjs/core/http';
|
|
2
|
+
import type { ApplicationService, ConfigProvider } from '@adonisjs/core/types';
|
|
3
|
+
import type { AuthManager } from './auth_manager.js';
|
|
4
|
+
import type { GUARD_KNOWN_EVENTS } from './symbols.js';
|
|
5
|
+
/**
|
|
6
|
+
* A set of properties a guard must implement.
|
|
7
|
+
*/
|
|
8
|
+
export interface GuardContract<User> {
|
|
9
|
+
/**
|
|
10
|
+
* Reference to the currently authenticated user
|
|
11
|
+
*/
|
|
12
|
+
user?: User;
|
|
13
|
+
/**
|
|
14
|
+
* A boolean to know if the current request has
|
|
15
|
+
* been authenticated
|
|
16
|
+
*/
|
|
17
|
+
isAuthenticated: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Whether or not the authentication has been attempted
|
|
20
|
+
* during the current request
|
|
21
|
+
*/
|
|
22
|
+
authenticationAttempted: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Check if the current request has been
|
|
25
|
+
* authenticated without throwing an
|
|
26
|
+
* exception
|
|
27
|
+
*/
|
|
28
|
+
check(): Promise<boolean>;
|
|
29
|
+
/**
|
|
30
|
+
* Authenticates the current request and throws
|
|
31
|
+
* an exception if the request is not authenticated.
|
|
32
|
+
*/
|
|
33
|
+
authenticate(): Promise<User>;
|
|
34
|
+
/**
|
|
35
|
+
* A unique name for the guard driver
|
|
36
|
+
*/
|
|
37
|
+
driverName: string;
|
|
38
|
+
/**
|
|
39
|
+
* Aymbol for infer the events emitted by a specific
|
|
40
|
+
* guard
|
|
41
|
+
*/
|
|
42
|
+
[GUARD_KNOWN_EVENTS]: unknown;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The authenticator guard factory method is called by the
|
|
46
|
+
* Authenticator class to create an instance of a specific
|
|
47
|
+
* guard during an HTTP request
|
|
48
|
+
*/
|
|
49
|
+
export type GuardFactory = (ctx: HttpContext) => GuardContract<unknown>;
|
|
50
|
+
/**
|
|
51
|
+
* Authenticators are inferred inside the user application
|
|
52
|
+
* from the config file
|
|
53
|
+
*/
|
|
54
|
+
export interface Authenticators {
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Infer authenticators from the auth config
|
|
58
|
+
*/
|
|
59
|
+
export type InferAuthenticators<Config extends ConfigProvider<{
|
|
60
|
+
default: unknown;
|
|
61
|
+
guards: unknown;
|
|
62
|
+
}>> = Awaited<ReturnType<Config['resolver']>>['guards'];
|
|
63
|
+
/**
|
|
64
|
+
* Auth service is a singleton instance of the AuthManager
|
|
65
|
+
* configured using the config stored within the user
|
|
66
|
+
* app.
|
|
67
|
+
*/
|
|
68
|
+
export interface AuthService extends AuthManager<Authenticators extends Record<string, GuardFactory> ? Authenticators : never> {
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Config provider for exporting guard
|
|
72
|
+
*/
|
|
73
|
+
export type GuardConfigProvider<Guard extends GuardFactory> = {
|
|
74
|
+
resolver: (name: string, app: ApplicationService) => Promise<Guard>;
|
|
75
|
+
};
|