@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,15 @@
|
|
|
1
|
+
import { BaseLucidUserProvider } from '../../core/user_providers/lucid.js';
|
|
2
|
+
import { BaseDatabaseUserProvider } from '../../core/user_providers/database.js';
|
|
3
|
+
import type { LucidAuthenticatable, UserProviderContract } from '../../core/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Using lucid models to find users for session
|
|
6
|
+
* auth
|
|
7
|
+
*/
|
|
8
|
+
export declare class LucidUserProvider<UserModel extends LucidAuthenticatable> extends BaseLucidUserProvider<UserModel> implements UserProviderContract<InstanceType<UserModel>> {
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Using database query builder to find users for
|
|
12
|
+
* session auth
|
|
13
|
+
*/
|
|
14
|
+
export declare class DatabaseUserProvider<User extends Record<string, any>> extends BaseDatabaseUserProvider<User> implements UserProviderContract<User> {
|
|
15
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
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 { BaseLucidUserProvider } from '../../core/user_providers/lucid.js';
|
|
10
|
+
import { BaseDatabaseUserProvider } from '../../core/user_providers/database.js';
|
|
11
|
+
/**
|
|
12
|
+
* Using lucid models to find users for session
|
|
13
|
+
* auth
|
|
14
|
+
*/
|
|
15
|
+
export class LucidUserProvider extends BaseLucidUserProvider {
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Using database query builder to find users for
|
|
19
|
+
* session auth
|
|
20
|
+
*/
|
|
21
|
+
export class DatabaseUserProvider extends BaseDatabaseUserProvider {
|
|
22
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guard user represents a user independent of the storage
|
|
3
|
+
* provider. It contains a standard set of properties
|
|
4
|
+
* used by authentication guards to interact with
|
|
5
|
+
* a user.
|
|
6
|
+
*
|
|
7
|
+
* Think of it as a bridge between a user and the authentication
|
|
8
|
+
* guard.
|
|
9
|
+
*/
|
|
10
|
+
export declare abstract class GuardUser<RealUser> {
|
|
11
|
+
protected realUser: RealUser;
|
|
12
|
+
constructor(realUser: RealUser);
|
|
13
|
+
/**
|
|
14
|
+
* Verifies the plain text password against the user password
|
|
15
|
+
* hash
|
|
16
|
+
*/
|
|
17
|
+
abstract verifyPassword(plainTextPassword: string): Promise<boolean>;
|
|
18
|
+
/**
|
|
19
|
+
* Returns a value to uniquely identify the user.
|
|
20
|
+
*/
|
|
21
|
+
abstract getId(): number | string;
|
|
22
|
+
/**
|
|
23
|
+
* Returns the original provider specific user object.
|
|
24
|
+
*/
|
|
25
|
+
getOriginal(): RealUser;
|
|
26
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
/**
|
|
10
|
+
* Guard user represents a user independent of the storage
|
|
11
|
+
* provider. It contains a standard set of properties
|
|
12
|
+
* used by authentication guards to interact with
|
|
13
|
+
* a user.
|
|
14
|
+
*
|
|
15
|
+
* Think of it as a bridge between a user and the authentication
|
|
16
|
+
* guard.
|
|
17
|
+
*/
|
|
18
|
+
export class GuardUser {
|
|
19
|
+
realUser;
|
|
20
|
+
constructor(realUser) {
|
|
21
|
+
this.realUser = realUser;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Returns the original provider specific user object.
|
|
25
|
+
*/
|
|
26
|
+
getOriginal() {
|
|
27
|
+
return this.realUser;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { TokenContract } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* A token represents an opaque token issued to a client
|
|
4
|
+
* to perform a specific task.
|
|
5
|
+
*
|
|
6
|
+
* The raw value of a token is only visible at the time of
|
|
7
|
+
* issuing it and one must persist hash to the database.
|
|
8
|
+
*/
|
|
9
|
+
export declare abstract class Token implements TokenContract {
|
|
10
|
+
/**
|
|
11
|
+
* Series is a random number stored inside the database as it is
|
|
12
|
+
*/
|
|
13
|
+
series: string;
|
|
14
|
+
/**
|
|
15
|
+
* Value is a random number only available at the time of issuing
|
|
16
|
+
* the token. Afterwards, the value is undefined.
|
|
17
|
+
*/
|
|
18
|
+
value: string | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Hash reference to the token hash
|
|
21
|
+
*/
|
|
22
|
+
hash: string;
|
|
23
|
+
/**
|
|
24
|
+
* Token type to uniquely identify a bucket of tokens
|
|
25
|
+
*/
|
|
26
|
+
abstract readonly type: string;
|
|
27
|
+
/**
|
|
28
|
+
* Arbitary meta-data associated with the token
|
|
29
|
+
*/
|
|
30
|
+
metaData?: Record<string, any>;
|
|
31
|
+
/**
|
|
32
|
+
* Timestamp when the token will expire
|
|
33
|
+
*/
|
|
34
|
+
expiresAt?: Date;
|
|
35
|
+
/**
|
|
36
|
+
* Date/time when the token instance was created
|
|
37
|
+
*/
|
|
38
|
+
createdAt: Date;
|
|
39
|
+
/**
|
|
40
|
+
* Date/time when the token was updated
|
|
41
|
+
*/
|
|
42
|
+
updatedAt: Date;
|
|
43
|
+
constructor(
|
|
44
|
+
/**
|
|
45
|
+
* Series is a random number stored inside the database as it is
|
|
46
|
+
*/
|
|
47
|
+
series: string,
|
|
48
|
+
/**
|
|
49
|
+
* Value is a random number only available at the time of issuing
|
|
50
|
+
* the token. Afterwards, the value is undefined.
|
|
51
|
+
*/
|
|
52
|
+
value: string | undefined,
|
|
53
|
+
/**
|
|
54
|
+
* Hash reference to the token hash
|
|
55
|
+
*/
|
|
56
|
+
hash: string);
|
|
57
|
+
/**
|
|
58
|
+
* Define metadata for the token
|
|
59
|
+
*/
|
|
60
|
+
setMetaData(metaData: Record<string, any>): this;
|
|
61
|
+
/**
|
|
62
|
+
* Verifies the value of a token against the pre-defined hash
|
|
63
|
+
*/
|
|
64
|
+
verify(value: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Define the token expiresAt timestamp from a duration. The value
|
|
67
|
+
* value must be a number in seconds or a string expression.
|
|
68
|
+
*/
|
|
69
|
+
setExpiry(duration: string | number): void;
|
|
70
|
+
/**
|
|
71
|
+
* Creates token value, series, and hash
|
|
72
|
+
*/
|
|
73
|
+
static seed(size?: number): {
|
|
74
|
+
series: string;
|
|
75
|
+
value: string;
|
|
76
|
+
hash: string;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Decodes a publicly shared token and return the series
|
|
80
|
+
* and the token value from it.
|
|
81
|
+
*
|
|
82
|
+
* Returns null when unable to decode the token because of
|
|
83
|
+
* invalid format or encoding.
|
|
84
|
+
*/
|
|
85
|
+
static decode(value: string): null | {
|
|
86
|
+
series: string;
|
|
87
|
+
value: string;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
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 { createHash } from 'node:crypto';
|
|
10
|
+
import string from '@adonisjs/core/helpers/string';
|
|
11
|
+
import { base64, safeEqual } from '@adonisjs/core/helpers';
|
|
12
|
+
/**
|
|
13
|
+
* A token represents an opaque token issued to a client
|
|
14
|
+
* to perform a specific task.
|
|
15
|
+
*
|
|
16
|
+
* The raw value of a token is only visible at the time of
|
|
17
|
+
* issuing it and one must persist hash to the database.
|
|
18
|
+
*/
|
|
19
|
+
export class Token {
|
|
20
|
+
series;
|
|
21
|
+
value;
|
|
22
|
+
hash;
|
|
23
|
+
/**
|
|
24
|
+
* Arbitary meta-data associated with the token
|
|
25
|
+
*/
|
|
26
|
+
metaData;
|
|
27
|
+
/**
|
|
28
|
+
* Timestamp when the token will expire
|
|
29
|
+
*/
|
|
30
|
+
expiresAt;
|
|
31
|
+
/**
|
|
32
|
+
* Date/time when the token instance was created
|
|
33
|
+
*/
|
|
34
|
+
createdAt = new Date();
|
|
35
|
+
/**
|
|
36
|
+
* Date/time when the token was updated
|
|
37
|
+
*/
|
|
38
|
+
updatedAt = new Date();
|
|
39
|
+
constructor(
|
|
40
|
+
/**
|
|
41
|
+
* Series is a random number stored inside the database as it is
|
|
42
|
+
*/
|
|
43
|
+
series,
|
|
44
|
+
/**
|
|
45
|
+
* Value is a random number only available at the time of issuing
|
|
46
|
+
* the token. Afterwards, the value is undefined.
|
|
47
|
+
*/
|
|
48
|
+
value,
|
|
49
|
+
/**
|
|
50
|
+
* Hash reference to the token hash
|
|
51
|
+
*/
|
|
52
|
+
hash) {
|
|
53
|
+
this.series = series;
|
|
54
|
+
this.value = value;
|
|
55
|
+
this.hash = hash;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Define metadata for the token
|
|
59
|
+
*/
|
|
60
|
+
setMetaData(metaData) {
|
|
61
|
+
this.metaData = metaData;
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Verifies the value of a token against the pre-defined hash
|
|
66
|
+
*/
|
|
67
|
+
verify(value) {
|
|
68
|
+
const newHash = createHash('sha256').update(value).digest('hex');
|
|
69
|
+
return safeEqual(this.hash, newHash);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Define the token expiresAt timestamp from a duration. The value
|
|
73
|
+
* value must be a number in seconds or a string expression.
|
|
74
|
+
*/
|
|
75
|
+
setExpiry(duration) {
|
|
76
|
+
/**
|
|
77
|
+
* Defining a date object and adding seconds since the
|
|
78
|
+
* creation of the token
|
|
79
|
+
*/
|
|
80
|
+
this.expiresAt = new Date();
|
|
81
|
+
this.expiresAt.setSeconds(this.createdAt.getSeconds() + string.seconds.parse(duration));
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Creates token value, series, and hash
|
|
85
|
+
*/
|
|
86
|
+
static seed(size = 30) {
|
|
87
|
+
const series = string.random(15);
|
|
88
|
+
const value = string.random(size);
|
|
89
|
+
const hash = createHash('sha256').update(value).digest('hex');
|
|
90
|
+
return { series, value: `${base64.urlEncode(series)}.${base64.urlEncode(value)}`, hash };
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Decodes a publicly shared token and return the series
|
|
94
|
+
* and the token value from it.
|
|
95
|
+
*
|
|
96
|
+
* Returns null when unable to decode the token because of
|
|
97
|
+
* invalid format or encoding.
|
|
98
|
+
*/
|
|
99
|
+
static decode(value) {
|
|
100
|
+
const [series, ...tokenValue] = value.split('.');
|
|
101
|
+
if (!series || tokenValue.length === 0) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
const decodedSeries = base64.urlDecode(series);
|
|
105
|
+
const decodedValue = base64.urlDecode(tokenValue.join('.'));
|
|
106
|
+
if (!decodedSeries || !decodedValue) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
series: decodedSeries,
|
|
111
|
+
value: decodedValue,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { Database } from '@adonisjs/lucid/database';
|
|
2
|
+
import type { DatabaseTokenProviderOptions, TokenProviderContract } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The representation of a token inside the database
|
|
5
|
+
*/
|
|
6
|
+
type DatabaseTokenRow = {
|
|
7
|
+
series: string;
|
|
8
|
+
user_id: string | number;
|
|
9
|
+
type: string;
|
|
10
|
+
token: string;
|
|
11
|
+
created_at: Date;
|
|
12
|
+
updated_at: Date;
|
|
13
|
+
expires_at: Date | null;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* A generic implementation to read tokens from the database
|
|
17
|
+
*/
|
|
18
|
+
export declare abstract class DatabaseTokenProvider<Token> implements TokenProviderContract<Token> {
|
|
19
|
+
/**
|
|
20
|
+
* Reference to the database query builder needed to
|
|
21
|
+
* query the database for tokens
|
|
22
|
+
*/
|
|
23
|
+
protected db: Database;
|
|
24
|
+
/**
|
|
25
|
+
* Options accepted
|
|
26
|
+
*/
|
|
27
|
+
protected options: DatabaseTokenProviderOptions;
|
|
28
|
+
constructor(
|
|
29
|
+
/**
|
|
30
|
+
* Reference to the database query builder needed to
|
|
31
|
+
* query the database for tokens
|
|
32
|
+
*/
|
|
33
|
+
db: Database,
|
|
34
|
+
/**
|
|
35
|
+
* Options accepted
|
|
36
|
+
*/
|
|
37
|
+
options: DatabaseTokenProviderOptions);
|
|
38
|
+
/**
|
|
39
|
+
* Should parse token to a database token row
|
|
40
|
+
*/
|
|
41
|
+
protected abstract parseToken(token: Token): DatabaseTokenRow;
|
|
42
|
+
/**
|
|
43
|
+
* Abstract method to prepare a token from the database
|
|
44
|
+
* row
|
|
45
|
+
*/
|
|
46
|
+
protected abstract prepareToken(dbRow: DatabaseTokenRow): Token;
|
|
47
|
+
/**
|
|
48
|
+
* Returns an instance of the query builder
|
|
49
|
+
*/
|
|
50
|
+
protected getQueryBuilder(): import("@adonisjs/lucid/types/querybuilder").DatabaseQueryBuilderContract<DatabaseTokenRow>;
|
|
51
|
+
/**
|
|
52
|
+
* Returns an instance of the query builder for insert
|
|
53
|
+
* queries
|
|
54
|
+
*/
|
|
55
|
+
protected getInsertQueryBuilder(): import("@adonisjs/lucid/types/querybuilder").InsertQueryBuilderContract<any[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Persists token inside the database
|
|
58
|
+
*/
|
|
59
|
+
createToken(token: Token): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Finds a token by series inside the database and returns an
|
|
62
|
+
* instance of it.
|
|
63
|
+
*
|
|
64
|
+
* Returns null if the token is missing or expired
|
|
65
|
+
*/
|
|
66
|
+
getTokenBySeries(series: string): Promise<Token | null>;
|
|
67
|
+
/**
|
|
68
|
+
* Removes a token from the database by the
|
|
69
|
+
* series number
|
|
70
|
+
*/
|
|
71
|
+
deleteTokenBySeries(series: string): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Updates token hash and expiry
|
|
74
|
+
*/
|
|
75
|
+
updateTokenBySeries(series: string, hash: string, expiresAt: Date): Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
export {};
|
|
@@ -0,0 +1,113 @@
|
|
|
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 '../../auth/debug.js';
|
|
10
|
+
/**
|
|
11
|
+
* A generic implementation to read tokens from the database
|
|
12
|
+
*/
|
|
13
|
+
export class DatabaseTokenProvider {
|
|
14
|
+
db;
|
|
15
|
+
options;
|
|
16
|
+
constructor(
|
|
17
|
+
/**
|
|
18
|
+
* Reference to the database query builder needed to
|
|
19
|
+
* query the database for tokens
|
|
20
|
+
*/
|
|
21
|
+
db,
|
|
22
|
+
/**
|
|
23
|
+
* Options accepted
|
|
24
|
+
*/
|
|
25
|
+
options) {
|
|
26
|
+
this.db = db;
|
|
27
|
+
this.options = options;
|
|
28
|
+
debug('db_token_provider: options %O', options);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Returns an instance of the query builder
|
|
32
|
+
*/
|
|
33
|
+
getQueryBuilder() {
|
|
34
|
+
return this.db.connection(this.options.connection).query();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Returns an instance of the query builder for insert
|
|
38
|
+
* queries
|
|
39
|
+
*/
|
|
40
|
+
getInsertQueryBuilder() {
|
|
41
|
+
return this.db.connection(this.options.connection).insertQuery();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Persists token inside the database
|
|
45
|
+
*/
|
|
46
|
+
async createToken(token) {
|
|
47
|
+
const parsedToken = this.parseToken(token);
|
|
48
|
+
debug('db_token_provider: creating token %O', parsedToken);
|
|
49
|
+
await this.getInsertQueryBuilder()
|
|
50
|
+
.table(this.options.table)
|
|
51
|
+
.insert({
|
|
52
|
+
...parsedToken,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Finds a token by series inside the database and returns an
|
|
57
|
+
* instance of it.
|
|
58
|
+
*
|
|
59
|
+
* Returns null if the token is missing or expired
|
|
60
|
+
*/
|
|
61
|
+
async getTokenBySeries(series) {
|
|
62
|
+
debug('db_token_provider: reading token by series %s', series);
|
|
63
|
+
const token = await this.getQueryBuilder()
|
|
64
|
+
.from(this.options.table)
|
|
65
|
+
.where('series', series)
|
|
66
|
+
.limit(1)
|
|
67
|
+
.first();
|
|
68
|
+
if (!token) {
|
|
69
|
+
debug('db_token_provider:: token %O', token);
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
if (typeof token.expires_at === 'number') {
|
|
73
|
+
token.expires_at = new Date(token.expires_at);
|
|
74
|
+
}
|
|
75
|
+
if (typeof token.created_at === 'number') {
|
|
76
|
+
token.created_at = new Date(token.created_at);
|
|
77
|
+
}
|
|
78
|
+
if (typeof token.updated_at === 'number') {
|
|
79
|
+
token.updated_at = new Date(token.updated_at);
|
|
80
|
+
}
|
|
81
|
+
debug('db_token_provider:: token %O', token);
|
|
82
|
+
/**
|
|
83
|
+
* Return null when token has been expired
|
|
84
|
+
*/
|
|
85
|
+
if (token.expires_at && token.expires_at instanceof Date && token.expires_at < new Date()) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
return this.prepareToken(token);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Removes a token from the database by the
|
|
92
|
+
* series number
|
|
93
|
+
*/
|
|
94
|
+
async deleteTokenBySeries(series) {
|
|
95
|
+
debug('db_token_provider: deleting token by series %s', series);
|
|
96
|
+
await this.getQueryBuilder().from(this.options.table).where('series', series).del();
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Updates token hash and expiry
|
|
100
|
+
*/
|
|
101
|
+
async updateTokenBySeries(series, hash, expiresAt) {
|
|
102
|
+
const updatePayload = {
|
|
103
|
+
token: hash,
|
|
104
|
+
updated_at: new Date(),
|
|
105
|
+
expires_at: expiresAt,
|
|
106
|
+
};
|
|
107
|
+
debug('db_token_provider: updating token by series %s: %O', series, updatePayload);
|
|
108
|
+
await this.getQueryBuilder()
|
|
109
|
+
.from(this.options.table)
|
|
110
|
+
.where('series', series)
|
|
111
|
+
.update(updatePayload);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import type { QueryClientContract } from '@adonisjs/lucid/types/database';
|
|
2
|
+
import type { GuardUser } from './guard_user.js';
|
|
3
|
+
import type { PROVIDER_REAL_USER } from '../auth/symbols.js';
|
|
4
|
+
import type { LucidModel, LucidRow } from '@adonisjs/lucid/types/model';
|
|
5
|
+
/**
|
|
6
|
+
* A token represents an opaque token issued to a client
|
|
7
|
+
* to perform a specific task.
|
|
8
|
+
*
|
|
9
|
+
* The raw value of a token is only visible at the time of
|
|
10
|
+
* issuing it and one must persist hash to the database.
|
|
11
|
+
*/
|
|
12
|
+
export interface TokenContract {
|
|
13
|
+
/**
|
|
14
|
+
* Token type to uniquely identify a bucket of tokens
|
|
15
|
+
*/
|
|
16
|
+
readonly type: string;
|
|
17
|
+
/**
|
|
18
|
+
* The plain text value. Only exists when the token is first
|
|
19
|
+
* created
|
|
20
|
+
*/
|
|
21
|
+
value?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Additional metadata associated with the token.
|
|
24
|
+
*/
|
|
25
|
+
metaData?: Record<string, any>;
|
|
26
|
+
/**
|
|
27
|
+
* The token hash for persisting the token in a database
|
|
28
|
+
*/
|
|
29
|
+
hash: string;
|
|
30
|
+
/**
|
|
31
|
+
* A unique readable series counter to find the token inside the
|
|
32
|
+
* database.
|
|
33
|
+
*/
|
|
34
|
+
series: string;
|
|
35
|
+
/**
|
|
36
|
+
* Timestamp when the token was first persisted
|
|
37
|
+
*/
|
|
38
|
+
createdAt: Date;
|
|
39
|
+
/**
|
|
40
|
+
* Timestamp when the token was updated
|
|
41
|
+
*/
|
|
42
|
+
updatedAt: Date;
|
|
43
|
+
/**
|
|
44
|
+
* Timestamp when the token will expire
|
|
45
|
+
*/
|
|
46
|
+
expiresAt?: Date;
|
|
47
|
+
/**
|
|
48
|
+
* Verifies the raw text value against the hash
|
|
49
|
+
*/
|
|
50
|
+
verify(value: string): boolean;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The UserProvider is used to lookup a user for authentication
|
|
54
|
+
*/
|
|
55
|
+
export interface UserProviderContract<RealUser> {
|
|
56
|
+
[PROVIDER_REAL_USER]: RealUser;
|
|
57
|
+
/**
|
|
58
|
+
* Creates a user object that guards can use for
|
|
59
|
+
* authentication.
|
|
60
|
+
*/
|
|
61
|
+
createUserForGuard(user: RealUser): Promise<GuardUser<RealUser>>;
|
|
62
|
+
/**
|
|
63
|
+
* Find a user by uid. The uid could be one or multiple fields
|
|
64
|
+
* to unique identify a user.
|
|
65
|
+
*
|
|
66
|
+
* This method is called when finding a user for login
|
|
67
|
+
*/
|
|
68
|
+
findByUid(value: string | number): Promise<GuardUser<RealUser> | null>;
|
|
69
|
+
/**
|
|
70
|
+
* Find a user by unique primary id. This method is called when
|
|
71
|
+
* authenticating user from their session.
|
|
72
|
+
*/
|
|
73
|
+
findById(value: string | number): Promise<GuardUser<RealUser> | null>;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The TokenProvider is used to lookup/persist tokens during authentication
|
|
77
|
+
*/
|
|
78
|
+
export interface TokenProviderContract<Token> {
|
|
79
|
+
/**
|
|
80
|
+
* Returns a token by the series counter, or null when token is
|
|
81
|
+
* missing
|
|
82
|
+
*/
|
|
83
|
+
getTokenBySeries(series: string): Promise<Token | null>;
|
|
84
|
+
/**
|
|
85
|
+
* Deletes a token by the series counter
|
|
86
|
+
*/
|
|
87
|
+
deleteTokenBySeries(series: string): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Updates a token by the series counter
|
|
90
|
+
*/
|
|
91
|
+
updateTokenBySeries(series: string, hash: string, expiresAt: Date): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Creates a new token and persists it to the database
|
|
94
|
+
*/
|
|
95
|
+
createToken(token: Token): Promise<void>;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* A lucid model that can be used during authentication
|
|
99
|
+
*/
|
|
100
|
+
export type LucidAuthenticatable = LucidModel & {
|
|
101
|
+
new (): LucidRow & {
|
|
102
|
+
/**
|
|
103
|
+
* Verify the plain text password against the user password
|
|
104
|
+
* hash
|
|
105
|
+
*/
|
|
106
|
+
verifyPasswordForAuth(plainTextPassword: string): Promise<boolean>;
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Options accepted by the Lucid user provider
|
|
111
|
+
*/
|
|
112
|
+
export type LucidUserProviderOptions<Model extends LucidAuthenticatable> = {
|
|
113
|
+
/**
|
|
114
|
+
* Optionally define the connection to use when making database
|
|
115
|
+
* queries
|
|
116
|
+
*/
|
|
117
|
+
connection?: string;
|
|
118
|
+
/**
|
|
119
|
+
* Optionally define the query client instance to use for making
|
|
120
|
+
* database queries.
|
|
121
|
+
*
|
|
122
|
+
* When both "connection" and "client" are defined, the client will
|
|
123
|
+
* be given the preference.
|
|
124
|
+
*/
|
|
125
|
+
client?: QueryClientContract;
|
|
126
|
+
/**
|
|
127
|
+
* Model to use for authentication
|
|
128
|
+
*/
|
|
129
|
+
model: () => Promise<{
|
|
130
|
+
default: Model;
|
|
131
|
+
}>;
|
|
132
|
+
/**
|
|
133
|
+
* An array of uids to use when finding a user for login. Make
|
|
134
|
+
* sure all fields can be used to uniquely lookup a user.
|
|
135
|
+
*/
|
|
136
|
+
uids: Extract<keyof InstanceType<Model>, string>[];
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Options accepted by the Database user provider
|
|
140
|
+
*/
|
|
141
|
+
export type DatabaseUserProviderOptions<RealUser extends Record<string, any>> = {
|
|
142
|
+
/**
|
|
143
|
+
* Optionally define the connection to use when making database
|
|
144
|
+
* queries
|
|
145
|
+
*/
|
|
146
|
+
connection?: string;
|
|
147
|
+
/**
|
|
148
|
+
* Database table to query to find the user
|
|
149
|
+
*/
|
|
150
|
+
table: string;
|
|
151
|
+
/**
|
|
152
|
+
* Column name to read the hashed password
|
|
153
|
+
*/
|
|
154
|
+
passwordColumnName: string;
|
|
155
|
+
/**
|
|
156
|
+
* An array of uids to use when finding a user for login. Make
|
|
157
|
+
* sure all fields can be used to uniquely lookup a user.
|
|
158
|
+
*/
|
|
159
|
+
uids: Extract<keyof RealUser, string>[];
|
|
160
|
+
/**
|
|
161
|
+
* The name of the id column to unique identify the user.
|
|
162
|
+
*/
|
|
163
|
+
id: string;
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* Options accepted by the Database token provider
|
|
167
|
+
*/
|
|
168
|
+
export type DatabaseTokenProviderOptions = {
|
|
169
|
+
/**
|
|
170
|
+
* Optionally define the connection to use when making database
|
|
171
|
+
* queries
|
|
172
|
+
*/
|
|
173
|
+
connection?: string;
|
|
174
|
+
/**
|
|
175
|
+
* Database table to query to find the user
|
|
176
|
+
*/
|
|
177
|
+
table: string;
|
|
178
|
+
};
|