@quatrain/auth 1.2.1 → 1.2.2
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/dist/AbstractAuthAdapter.d.ts +76 -0
- package/dist/AbstractAuthAdapter.js +18 -0
- package/dist/Auth.d.ts +21 -0
- package/dist/Auth.js +21 -0
- package/dist/AuthenticationError.d.ts +4 -0
- package/dist/AuthenticationError.js +4 -0
- package/dist/MockAuthAdapter.d.ts +60 -0
- package/dist/MockAuthAdapter.js +60 -0
- package/package.json +3 -3
- package/src/AbstractAuthAdapter.ts +76 -0
- package/src/Auth.ts +21 -0
- package/src/AuthenticationError.ts +4 -0
- package/src/MockAuthAdapter.ts +60 -0
|
@@ -1,22 +1,98 @@
|
|
|
1
1
|
import { AuthParameters, AuthParametersKeys } from './Auth';
|
|
2
2
|
import { User } from '@quatrain/backend';
|
|
3
3
|
import { AuthInterface } from './types/AuthInterface';
|
|
4
|
+
/**
|
|
5
|
+
* Abstract base class that defines the contract for all authentication adapters.
|
|
6
|
+
* Implementations should adapt standard authentication methods to specific providers
|
|
7
|
+
* (e.g. Firebase, Supabase, basic auth).
|
|
8
|
+
*/
|
|
4
9
|
export declare abstract class AbstractAuthAdapter implements AuthInterface {
|
|
10
|
+
/** The `User` class reference to be used by the adapter. */
|
|
5
11
|
static UserClass: typeof User;
|
|
6
12
|
protected _alias: string;
|
|
7
13
|
protected _params: AuthParameters;
|
|
8
14
|
constructor(params?: AuthParameters);
|
|
15
|
+
/**
|
|
16
|
+
* Assigns a configuration parameter for the adapter.
|
|
17
|
+
*
|
|
18
|
+
* @param key - The parameter key.
|
|
19
|
+
* @param value - The parameter value.
|
|
20
|
+
*/
|
|
9
21
|
setParam(key: AuthParametersKeys, value: any): void;
|
|
22
|
+
/**
|
|
23
|
+
* Retrieves a configuration parameter.
|
|
24
|
+
*
|
|
25
|
+
* @param key - The parameter key to fetch.
|
|
26
|
+
* @returns The corresponding configuration value.
|
|
27
|
+
*/
|
|
10
28
|
getParam(key: AuthParametersKeys): any;
|
|
11
29
|
set alias(alias: string);
|
|
12
30
|
get alias(): string;
|
|
31
|
+
/**
|
|
32
|
+
* Registers a new user directly in the authentication provider.
|
|
33
|
+
*
|
|
34
|
+
* @param user - The User object.
|
|
35
|
+
* @param clearPassword - The plaintext password.
|
|
36
|
+
* @returns A promise resolving to the registration response.
|
|
37
|
+
*/
|
|
13
38
|
abstract register(user: User, clearPassword?: string): Promise<any>;
|
|
39
|
+
/**
|
|
40
|
+
* Authenticates a user by login and password (generates tokens).
|
|
41
|
+
*
|
|
42
|
+
* @param login - User's email or login name.
|
|
43
|
+
* @param password - Plaintext password.
|
|
44
|
+
* @returns A promise resolving to the token payload.
|
|
45
|
+
*/
|
|
14
46
|
abstract signup(login: string, password: string): Promise<any>;
|
|
47
|
+
/**
|
|
48
|
+
* Terminates the current authentication session.
|
|
49
|
+
*
|
|
50
|
+
* @param user - The User footprint.
|
|
51
|
+
* @returns A promise resolving to the provider's signout response.
|
|
52
|
+
*/
|
|
15
53
|
abstract signout(user: User): Promise<any>;
|
|
54
|
+
/**
|
|
55
|
+
* Updates user credentials or metadata within the external auth provider.
|
|
56
|
+
*
|
|
57
|
+
* @param user - The User to modify.
|
|
58
|
+
* @param updatable - The delta payload of properties to update.
|
|
59
|
+
* @returns A promise resolving when the update completes.
|
|
60
|
+
*/
|
|
16
61
|
abstract update(user: User, updatable: any): Promise<any>;
|
|
62
|
+
/**
|
|
63
|
+
* Hard-deletes a user from the authentication provider.
|
|
64
|
+
*
|
|
65
|
+
* @param user - The User to delete.
|
|
66
|
+
* @returns A promise resolving on successful deletion.
|
|
67
|
+
*/
|
|
17
68
|
abstract delete(user: User): Promise<any>;
|
|
69
|
+
/**
|
|
70
|
+
* Validates and decodes an incoming authentication token.
|
|
71
|
+
*
|
|
72
|
+
* @param token - The raw token string (e.g. JWT).
|
|
73
|
+
* @returns The decoded token data payload.
|
|
74
|
+
*/
|
|
18
75
|
abstract getAuthToken(token: string): any;
|
|
76
|
+
/**
|
|
77
|
+
* Refreshes an expired access token using a valid refresh token.
|
|
78
|
+
*
|
|
79
|
+
* @param refreshToken - The refresh token string.
|
|
80
|
+
* @returns A promise resolving to the new access token payload.
|
|
81
|
+
*/
|
|
19
82
|
abstract refreshToken(refreshToken: string): Promise<any>;
|
|
83
|
+
/**
|
|
84
|
+
* Invalidates a specific access token explicitly.
|
|
85
|
+
*
|
|
86
|
+
* @param token - The token string to revoke.
|
|
87
|
+
* @returns Action response from the provider.
|
|
88
|
+
*/
|
|
20
89
|
abstract revokeAuthToken(token: string): any;
|
|
90
|
+
/**
|
|
91
|
+
* Injects custom claims (e.g. role, tenant info) into the user's token structure.
|
|
92
|
+
*
|
|
93
|
+
* @param id - The user ID.
|
|
94
|
+
* @param claims - The payload of claims to merge.
|
|
95
|
+
* @returns Action response from the provider.
|
|
96
|
+
*/
|
|
21
97
|
abstract setCustomUserClaims(id: string, claims: any): any;
|
|
22
98
|
}
|
|
@@ -2,15 +2,32 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AbstractAuthAdapter = void 0;
|
|
4
4
|
const backend_1 = require("@quatrain/backend");
|
|
5
|
+
/**
|
|
6
|
+
* Abstract base class that defines the contract for all authentication adapters.
|
|
7
|
+
* Implementations should adapt standard authentication methods to specific providers
|
|
8
|
+
* (e.g. Firebase, Supabase, basic auth).
|
|
9
|
+
*/
|
|
5
10
|
class AbstractAuthAdapter {
|
|
6
11
|
constructor(params = {}) {
|
|
7
12
|
this._alias = '';
|
|
8
13
|
this._params = {};
|
|
9
14
|
this._params = params;
|
|
10
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Assigns a configuration parameter for the adapter.
|
|
18
|
+
*
|
|
19
|
+
* @param key - The parameter key.
|
|
20
|
+
* @param value - The parameter value.
|
|
21
|
+
*/
|
|
11
22
|
setParam(key, value) {
|
|
12
23
|
this._params[key] = value;
|
|
13
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Retrieves a configuration parameter.
|
|
27
|
+
*
|
|
28
|
+
* @param key - The parameter key to fetch.
|
|
29
|
+
* @returns The corresponding configuration value.
|
|
30
|
+
*/
|
|
14
31
|
getParam(key) {
|
|
15
32
|
return this._params[key];
|
|
16
33
|
}
|
|
@@ -22,4 +39,5 @@ class AbstractAuthAdapter {
|
|
|
22
39
|
}
|
|
23
40
|
}
|
|
24
41
|
exports.AbstractAuthAdapter = AbstractAuthAdapter;
|
|
42
|
+
/** The `User` class reference to be used by the adapter. */
|
|
25
43
|
AbstractAuthAdapter.UserClass = backend_1.User;
|
package/dist/Auth.d.ts
CHANGED
|
@@ -26,11 +26,32 @@ export interface AuthAdapter extends AbstractAuthAdapter {
|
|
|
26
26
|
export type AuthRegistry<T extends AbstractAuthAdapter> = {
|
|
27
27
|
[x: string]: T;
|
|
28
28
|
};
|
|
29
|
+
/**
|
|
30
|
+
* Global authentication manager handling registration and retrieval
|
|
31
|
+
* of diverse Auth providers (adapters) via an alias registry.
|
|
32
|
+
*/
|
|
29
33
|
export declare class Auth extends Core {
|
|
34
|
+
/** The fallback provider alias. */
|
|
30
35
|
static defaultProvider: string;
|
|
36
|
+
/** Core logger dedicated to Auth actions. */
|
|
31
37
|
static logger: any;
|
|
38
|
+
/** Standardized error message for duplicate email constraint violations. */
|
|
32
39
|
static ERROR_EMAIL_EXISTS: string;
|
|
33
40
|
protected static _providers: AuthRegistry<any>;
|
|
41
|
+
/**
|
|
42
|
+
* Registers a configured auth provider into the global context.
|
|
43
|
+
*
|
|
44
|
+
* @param provider - Instantiated auth adapter.
|
|
45
|
+
* @param alias - Short identifier name.
|
|
46
|
+
* @param setDefault - If true, marks this adapter as the fallback provider.
|
|
47
|
+
*/
|
|
34
48
|
static addProvider(provider: AbstractAuthAdapter, alias: string, setDefault?: boolean): void;
|
|
49
|
+
/**
|
|
50
|
+
* Fetches a registered provider by its alias.
|
|
51
|
+
*
|
|
52
|
+
* @param alias - Requested provider identifier. Defaults to `defaultProvider`.
|
|
53
|
+
* @returns The corresponding auth adapter.
|
|
54
|
+
* @throws {Error} If the specified alias is unknown.
|
|
55
|
+
*/
|
|
35
56
|
static getProvider<T extends AbstractAuthAdapter>(alias?: string): T;
|
|
36
57
|
}
|
package/dist/Auth.js
CHANGED
|
@@ -9,13 +9,31 @@ var AuthAction;
|
|
|
9
9
|
AuthAction["SIGNUP"] = "signup";
|
|
10
10
|
AuthAction["SIGNOUT"] = "signout";
|
|
11
11
|
})(AuthAction || (exports.AuthAction = AuthAction = {}));
|
|
12
|
+
/**
|
|
13
|
+
* Global authentication manager handling registration and retrieval
|
|
14
|
+
* of diverse Auth providers (adapters) via an alias registry.
|
|
15
|
+
*/
|
|
12
16
|
class Auth extends core_1.Core {
|
|
17
|
+
/**
|
|
18
|
+
* Registers a configured auth provider into the global context.
|
|
19
|
+
*
|
|
20
|
+
* @param provider - Instantiated auth adapter.
|
|
21
|
+
* @param alias - Short identifier name.
|
|
22
|
+
* @param setDefault - If true, marks this adapter as the fallback provider.
|
|
23
|
+
*/
|
|
13
24
|
static addProvider(provider, alias, setDefault = false) {
|
|
14
25
|
this._providers[alias] = provider;
|
|
15
26
|
if (setDefault) {
|
|
16
27
|
this.defaultProvider = alias;
|
|
17
28
|
}
|
|
18
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Fetches a registered provider by its alias.
|
|
32
|
+
*
|
|
33
|
+
* @param alias - Requested provider identifier. Defaults to `defaultProvider`.
|
|
34
|
+
* @returns The corresponding auth adapter.
|
|
35
|
+
* @throws {Error} If the specified alias is unknown.
|
|
36
|
+
*/
|
|
19
37
|
static getProvider(alias = this.defaultProvider) {
|
|
20
38
|
if (this._providers[alias]) {
|
|
21
39
|
return this._providers[alias];
|
|
@@ -27,7 +45,10 @@ class Auth extends core_1.Core {
|
|
|
27
45
|
}
|
|
28
46
|
exports.Auth = Auth;
|
|
29
47
|
_a = Auth;
|
|
48
|
+
/** The fallback provider alias. */
|
|
30
49
|
Auth.defaultProvider = 'default';
|
|
50
|
+
/** Core logger dedicated to Auth actions. */
|
|
31
51
|
Auth.logger = _a.addLogger('Auth');
|
|
52
|
+
/** Standardized error message for duplicate email constraint violations. */
|
|
32
53
|
Auth.ERROR_EMAIL_EXISTS = `User email already exists`;
|
|
33
54
|
Auth._providers = {};
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AuthenticationError = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Standard exception representing authentication failures, invalid credentials,
|
|
6
|
+
* or token expiration events.
|
|
7
|
+
*/
|
|
4
8
|
class AuthenticationError extends Error {
|
|
5
9
|
}
|
|
6
10
|
exports.AuthenticationError = AuthenticationError;
|
|
@@ -9,16 +9,76 @@ export declare class MockAuthAdapter extends AbstractAuthAdapter {
|
|
|
9
9
|
private tokens;
|
|
10
10
|
private refreshTokens;
|
|
11
11
|
constructor(params?: AuthParameters);
|
|
12
|
+
/**
|
|
13
|
+
* Mock registration. Stores the user in memory mapped by email.
|
|
14
|
+
*
|
|
15
|
+
* @param user - Target user.
|
|
16
|
+
* @param clearPassword - Ignored in mock context.
|
|
17
|
+
* @returns A mock success promise.
|
|
18
|
+
*/
|
|
12
19
|
register(user: User, clearPassword?: string): Promise<any>;
|
|
20
|
+
/**
|
|
21
|
+
* Mock signup. Generates mock JWT tokens assuming the login is valid.
|
|
22
|
+
*
|
|
23
|
+
* @param login - Mock user identifier.
|
|
24
|
+
* @param password - Mock password.
|
|
25
|
+
* @returns Emulated auth response payload.
|
|
26
|
+
*/
|
|
13
27
|
signup(login: string, password: string): Promise<any>;
|
|
28
|
+
/**
|
|
29
|
+
* Deletes active tokens tied to the provided mock user.
|
|
30
|
+
*
|
|
31
|
+
* @param user - User instance to sign out.
|
|
32
|
+
*/
|
|
14
33
|
signout(user: User): Promise<any>;
|
|
34
|
+
/**
|
|
35
|
+
* Mock user state update in memory.
|
|
36
|
+
*
|
|
37
|
+
* @param user - Target user.
|
|
38
|
+
* @param updatable - Property modifications.
|
|
39
|
+
*/
|
|
15
40
|
update(user: User, updatable: any): Promise<any>;
|
|
41
|
+
/**
|
|
42
|
+
* Evicts the user and all associated mock tokens from memory.
|
|
43
|
+
*
|
|
44
|
+
* @param user - User instance to delete.
|
|
45
|
+
*/
|
|
16
46
|
delete(user: User): Promise<any>;
|
|
47
|
+
/**
|
|
48
|
+
* Reads the cached token data payload.
|
|
49
|
+
*
|
|
50
|
+
* @param token - Raw mock token string.
|
|
51
|
+
*/
|
|
17
52
|
getAuthToken(token: string): any;
|
|
53
|
+
/**
|
|
54
|
+
* Cycles an old refresh token for a completely new session pair.
|
|
55
|
+
*
|
|
56
|
+
* @param refreshToken - Active mock refresh token string.
|
|
57
|
+
*/
|
|
18
58
|
refreshToken(refreshToken: string): Promise<any>;
|
|
59
|
+
/**
|
|
60
|
+
* Blacklists a specific access token.
|
|
61
|
+
*
|
|
62
|
+
* @param token - Target mock token to drop.
|
|
63
|
+
*/
|
|
19
64
|
revokeAuthToken(token: string): any;
|
|
65
|
+
/**
|
|
66
|
+
* Manually appends structural role claims onto a registered mock user.
|
|
67
|
+
*
|
|
68
|
+
* @param id - Mock user ID.
|
|
69
|
+
* @param claims - Payload to merge.
|
|
70
|
+
*/
|
|
20
71
|
setCustomUserClaims(id: string, claims: any): any;
|
|
72
|
+
/**
|
|
73
|
+
* Test utility: Flushes all internal registers.
|
|
74
|
+
*/
|
|
21
75
|
clearAll(): void;
|
|
76
|
+
/**
|
|
77
|
+
* Test utility: Retrieves user instance by its stored key (email).
|
|
78
|
+
*/
|
|
22
79
|
getUserByEmail(email: string): User | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Test utility: Asserts the existence of an active token.
|
|
82
|
+
*/
|
|
23
83
|
hasToken(token: string): boolean;
|
|
24
84
|
}
|
package/dist/MockAuthAdapter.js
CHANGED
|
@@ -21,6 +21,13 @@ class MockAuthAdapter extends AbstractAuthAdapter_1.AbstractAuthAdapter {
|
|
|
21
21
|
this.tokens = new Map();
|
|
22
22
|
this.refreshTokens = new Map();
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Mock registration. Stores the user in memory mapped by email.
|
|
26
|
+
*
|
|
27
|
+
* @param user - Target user.
|
|
28
|
+
* @param clearPassword - Ignored in mock context.
|
|
29
|
+
* @returns A mock success promise.
|
|
30
|
+
*/
|
|
24
31
|
register(user, clearPassword) {
|
|
25
32
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26
33
|
if (this.registeredUsers.has(user._.email)) {
|
|
@@ -30,6 +37,13 @@ class MockAuthAdapter extends AbstractAuthAdapter_1.AbstractAuthAdapter {
|
|
|
30
37
|
return { success: true, user };
|
|
31
38
|
});
|
|
32
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Mock signup. Generates mock JWT tokens assuming the login is valid.
|
|
42
|
+
*
|
|
43
|
+
* @param login - Mock user identifier.
|
|
44
|
+
* @param password - Mock password.
|
|
45
|
+
* @returns Emulated auth response payload.
|
|
46
|
+
*/
|
|
33
47
|
signup(login, password) {
|
|
34
48
|
return __awaiter(this, void 0, void 0, function* () {
|
|
35
49
|
const user = this.registeredUsers.get(login);
|
|
@@ -48,6 +62,11 @@ class MockAuthAdapter extends AbstractAuthAdapter_1.AbstractAuthAdapter {
|
|
|
48
62
|
};
|
|
49
63
|
});
|
|
50
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Deletes active tokens tied to the provided mock user.
|
|
67
|
+
*
|
|
68
|
+
* @param user - User instance to sign out.
|
|
69
|
+
*/
|
|
51
70
|
signout(user) {
|
|
52
71
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53
72
|
// Remove all tokens associated with this user
|
|
@@ -59,6 +78,12 @@ class MockAuthAdapter extends AbstractAuthAdapter_1.AbstractAuthAdapter {
|
|
|
59
78
|
return { success: true };
|
|
60
79
|
});
|
|
61
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Mock user state update in memory.
|
|
83
|
+
*
|
|
84
|
+
* @param user - Target user.
|
|
85
|
+
* @param updatable - Property modifications.
|
|
86
|
+
*/
|
|
62
87
|
update(user, updatable) {
|
|
63
88
|
return __awaiter(this, void 0, void 0, function* () {
|
|
64
89
|
const existingUser = this.registeredUsers.get(user._.email);
|
|
@@ -70,6 +95,11 @@ class MockAuthAdapter extends AbstractAuthAdapter_1.AbstractAuthAdapter {
|
|
|
70
95
|
return { success: true, user: updatedUser };
|
|
71
96
|
});
|
|
72
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Evicts the user and all associated mock tokens from memory.
|
|
100
|
+
*
|
|
101
|
+
* @param user - User instance to delete.
|
|
102
|
+
*/
|
|
73
103
|
delete(user) {
|
|
74
104
|
return __awaiter(this, void 0, void 0, function* () {
|
|
75
105
|
if (!this.registeredUsers.has(user._.email)) {
|
|
@@ -80,6 +110,11 @@ class MockAuthAdapter extends AbstractAuthAdapter_1.AbstractAuthAdapter {
|
|
|
80
110
|
return { success: true };
|
|
81
111
|
});
|
|
82
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Reads the cached token data payload.
|
|
115
|
+
*
|
|
116
|
+
* @param token - Raw mock token string.
|
|
117
|
+
*/
|
|
83
118
|
getAuthToken(token) {
|
|
84
119
|
const tokenData = this.tokens.get(token);
|
|
85
120
|
if (!tokenData) {
|
|
@@ -87,6 +122,11 @@ class MockAuthAdapter extends AbstractAuthAdapter_1.AbstractAuthAdapter {
|
|
|
87
122
|
}
|
|
88
123
|
return tokenData;
|
|
89
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Cycles an old refresh token for a completely new session pair.
|
|
127
|
+
*
|
|
128
|
+
* @param refreshToken - Active mock refresh token string.
|
|
129
|
+
*/
|
|
90
130
|
refreshToken(refreshToken) {
|
|
91
131
|
return __awaiter(this, void 0, void 0, function* () {
|
|
92
132
|
const oldToken = this.refreshTokens.get(refreshToken);
|
|
@@ -113,6 +153,11 @@ class MockAuthAdapter extends AbstractAuthAdapter_1.AbstractAuthAdapter {
|
|
|
113
153
|
};
|
|
114
154
|
});
|
|
115
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Blacklists a specific access token.
|
|
158
|
+
*
|
|
159
|
+
* @param token - Target mock token to drop.
|
|
160
|
+
*/
|
|
116
161
|
revokeAuthToken(token) {
|
|
117
162
|
if (!this.tokens.has(token)) {
|
|
118
163
|
throw new Error('Token not found');
|
|
@@ -127,6 +172,12 @@ class MockAuthAdapter extends AbstractAuthAdapter_1.AbstractAuthAdapter {
|
|
|
127
172
|
}
|
|
128
173
|
return { success: true };
|
|
129
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Manually appends structural role claims onto a registered mock user.
|
|
177
|
+
*
|
|
178
|
+
* @param id - Mock user ID.
|
|
179
|
+
* @param claims - Payload to merge.
|
|
180
|
+
*/
|
|
130
181
|
setCustomUserClaims(id, claims) {
|
|
131
182
|
// Find user by id and set custom claims
|
|
132
183
|
for (const [email, user] of this.registeredUsers.entries()) {
|
|
@@ -139,14 +190,23 @@ class MockAuthAdapter extends AbstractAuthAdapter_1.AbstractAuthAdapter {
|
|
|
139
190
|
throw new Error('User not found');
|
|
140
191
|
}
|
|
141
192
|
// Helper methods for testing
|
|
193
|
+
/**
|
|
194
|
+
* Test utility: Flushes all internal registers.
|
|
195
|
+
*/
|
|
142
196
|
clearAll() {
|
|
143
197
|
this.registeredUsers.clear();
|
|
144
198
|
this.tokens.clear();
|
|
145
199
|
this.refreshTokens.clear();
|
|
146
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Test utility: Retrieves user instance by its stored key (email).
|
|
203
|
+
*/
|
|
147
204
|
getUserByEmail(email) {
|
|
148
205
|
return this.registeredUsers.get(email);
|
|
149
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Test utility: Asserts the existence of an active token.
|
|
209
|
+
*/
|
|
150
210
|
hasToken(token) {
|
|
151
211
|
return this.tokens.has(token);
|
|
152
212
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quatrain/auth",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"description": "Auth adapters commons",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
},
|
|
21
21
|
"author": "Quatrain Développement SAS <developers@quatrain.com>",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@quatrain/backend": "^1.
|
|
24
|
-
"@quatrain/core": "^1.
|
|
23
|
+
"@quatrain/backend": "^1.2.6",
|
|
24
|
+
"@quatrain/core": "^1.2.5"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@tsconfig/recommended": "^1.0.1",
|
|
@@ -2,7 +2,13 @@ import { AuthParameters, AuthParametersKeys } from './Auth'
|
|
|
2
2
|
import { User } from '@quatrain/backend'
|
|
3
3
|
import { AuthInterface } from './types/AuthInterface'
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Abstract base class that defines the contract for all authentication adapters.
|
|
7
|
+
* Implementations should adapt standard authentication methods to specific providers
|
|
8
|
+
* (e.g. Firebase, Supabase, basic auth).
|
|
9
|
+
*/
|
|
5
10
|
export abstract class AbstractAuthAdapter implements AuthInterface {
|
|
11
|
+
/** The `User` class reference to be used by the adapter. */
|
|
6
12
|
static UserClass = User
|
|
7
13
|
protected _alias: string = ''
|
|
8
14
|
protected _params: AuthParameters = {}
|
|
@@ -11,10 +17,22 @@ export abstract class AbstractAuthAdapter implements AuthInterface {
|
|
|
11
17
|
this._params = params
|
|
12
18
|
}
|
|
13
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Assigns a configuration parameter for the adapter.
|
|
22
|
+
*
|
|
23
|
+
* @param key - The parameter key.
|
|
24
|
+
* @param value - The parameter value.
|
|
25
|
+
*/
|
|
14
26
|
setParam(key: AuthParametersKeys, value: any) {
|
|
15
27
|
this._params[key] = value
|
|
16
28
|
}
|
|
17
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Retrieves a configuration parameter.
|
|
32
|
+
*
|
|
33
|
+
* @param key - The parameter key to fetch.
|
|
34
|
+
* @returns The corresponding configuration value.
|
|
35
|
+
*/
|
|
18
36
|
getParam(key: AuthParametersKeys) {
|
|
19
37
|
return this._params[key]
|
|
20
38
|
}
|
|
@@ -27,21 +45,79 @@ export abstract class AbstractAuthAdapter implements AuthInterface {
|
|
|
27
45
|
return this._alias
|
|
28
46
|
}
|
|
29
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Registers a new user directly in the authentication provider.
|
|
50
|
+
*
|
|
51
|
+
* @param user - The User object.
|
|
52
|
+
* @param clearPassword - The plaintext password.
|
|
53
|
+
* @returns A promise resolving to the registration response.
|
|
54
|
+
*/
|
|
30
55
|
abstract register(user: User, clearPassword?: string): Promise<any>
|
|
31
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Authenticates a user by login and password (generates tokens).
|
|
59
|
+
*
|
|
60
|
+
* @param login - User's email or login name.
|
|
61
|
+
* @param password - Plaintext password.
|
|
62
|
+
* @returns A promise resolving to the token payload.
|
|
63
|
+
*/
|
|
32
64
|
abstract signup(login: string, password: string): Promise<any>
|
|
33
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Terminates the current authentication session.
|
|
68
|
+
*
|
|
69
|
+
* @param user - The User footprint.
|
|
70
|
+
* @returns A promise resolving to the provider's signout response.
|
|
71
|
+
*/
|
|
34
72
|
abstract signout(user: User): Promise<any>
|
|
35
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Updates user credentials or metadata within the external auth provider.
|
|
76
|
+
*
|
|
77
|
+
* @param user - The User to modify.
|
|
78
|
+
* @param updatable - The delta payload of properties to update.
|
|
79
|
+
* @returns A promise resolving when the update completes.
|
|
80
|
+
*/
|
|
36
81
|
abstract update(user: User, updatable: any): Promise<any>
|
|
37
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Hard-deletes a user from the authentication provider.
|
|
85
|
+
*
|
|
86
|
+
* @param user - The User to delete.
|
|
87
|
+
* @returns A promise resolving on successful deletion.
|
|
88
|
+
*/
|
|
38
89
|
abstract delete(user: User): Promise<any>
|
|
39
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Validates and decodes an incoming authentication token.
|
|
93
|
+
*
|
|
94
|
+
* @param token - The raw token string (e.g. JWT).
|
|
95
|
+
* @returns The decoded token data payload.
|
|
96
|
+
*/
|
|
40
97
|
abstract getAuthToken(token: string): any
|
|
41
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Refreshes an expired access token using a valid refresh token.
|
|
101
|
+
*
|
|
102
|
+
* @param refreshToken - The refresh token string.
|
|
103
|
+
* @returns A promise resolving to the new access token payload.
|
|
104
|
+
*/
|
|
42
105
|
abstract refreshToken(refreshToken: string): Promise<any>
|
|
43
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Invalidates a specific access token explicitly.
|
|
109
|
+
*
|
|
110
|
+
* @param token - The token string to revoke.
|
|
111
|
+
* @returns Action response from the provider.
|
|
112
|
+
*/
|
|
44
113
|
abstract revokeAuthToken(token: string): any
|
|
45
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Injects custom claims (e.g. role, tenant info) into the user's token structure.
|
|
117
|
+
*
|
|
118
|
+
* @param id - The user ID.
|
|
119
|
+
* @param claims - The payload of claims to merge.
|
|
120
|
+
* @returns Action response from the provider.
|
|
121
|
+
*/
|
|
46
122
|
abstract setCustomUserClaims(id: string, claims: any): any
|
|
47
123
|
}
|
package/src/Auth.ts
CHANGED
|
@@ -35,15 +35,29 @@ export interface AuthAdapter extends AbstractAuthAdapter {}
|
|
|
35
35
|
|
|
36
36
|
export type AuthRegistry<T extends AbstractAuthAdapter> = { [x: string]: T }
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Global authentication manager handling registration and retrieval
|
|
40
|
+
* of diverse Auth providers (adapters) via an alias registry.
|
|
41
|
+
*/
|
|
38
42
|
export class Auth extends Core {
|
|
43
|
+
/** The fallback provider alias. */
|
|
39
44
|
static defaultProvider = 'default'
|
|
45
|
+
/** Core logger dedicated to Auth actions. */
|
|
40
46
|
static logger = this.addLogger('Auth')
|
|
41
47
|
|
|
42
48
|
|
|
49
|
+
/** Standardized error message for duplicate email constraint violations. */
|
|
43
50
|
static ERROR_EMAIL_EXISTS = `User email already exists`
|
|
44
51
|
|
|
45
52
|
protected static _providers: AuthRegistry<any> = {}
|
|
46
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Registers a configured auth provider into the global context.
|
|
56
|
+
*
|
|
57
|
+
* @param provider - Instantiated auth adapter.
|
|
58
|
+
* @param alias - Short identifier name.
|
|
59
|
+
* @param setDefault - If true, marks this adapter as the fallback provider.
|
|
60
|
+
*/
|
|
47
61
|
static addProvider(
|
|
48
62
|
provider: AbstractAuthAdapter,
|
|
49
63
|
alias: string,
|
|
@@ -55,6 +69,13 @@ export class Auth extends Core {
|
|
|
55
69
|
}
|
|
56
70
|
}
|
|
57
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Fetches a registered provider by its alias.
|
|
74
|
+
*
|
|
75
|
+
* @param alias - Requested provider identifier. Defaults to `defaultProvider`.
|
|
76
|
+
* @returns The corresponding auth adapter.
|
|
77
|
+
* @throws {Error} If the specified alias is unknown.
|
|
78
|
+
*/
|
|
58
79
|
static getProvider<T extends AbstractAuthAdapter>(
|
|
59
80
|
alias: string = this.defaultProvider
|
|
60
81
|
): T {
|
package/src/MockAuthAdapter.ts
CHANGED
|
@@ -14,6 +14,13 @@ export class MockAuthAdapter extends AbstractAuthAdapter {
|
|
|
14
14
|
super(params)
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Mock registration. Stores the user in memory mapped by email.
|
|
19
|
+
*
|
|
20
|
+
* @param user - Target user.
|
|
21
|
+
* @param clearPassword - Ignored in mock context.
|
|
22
|
+
* @returns A mock success promise.
|
|
23
|
+
*/
|
|
17
24
|
async register(user: User, clearPassword?: string): Promise<any> {
|
|
18
25
|
if (this.registeredUsers.has(user._.email)) {
|
|
19
26
|
throw new Error('User email already exists')
|
|
@@ -22,6 +29,13 @@ export class MockAuthAdapter extends AbstractAuthAdapter {
|
|
|
22
29
|
return { success: true, user }
|
|
23
30
|
}
|
|
24
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Mock signup. Generates mock JWT tokens assuming the login is valid.
|
|
34
|
+
*
|
|
35
|
+
* @param login - Mock user identifier.
|
|
36
|
+
* @param password - Mock password.
|
|
37
|
+
* @returns Emulated auth response payload.
|
|
38
|
+
*/
|
|
25
39
|
async signup(login: string, password: string): Promise<any> {
|
|
26
40
|
const user = this.registeredUsers.get(login)
|
|
27
41
|
if (!user) {
|
|
@@ -42,6 +56,11 @@ export class MockAuthAdapter extends AbstractAuthAdapter {
|
|
|
42
56
|
}
|
|
43
57
|
}
|
|
44
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Deletes active tokens tied to the provided mock user.
|
|
61
|
+
*
|
|
62
|
+
* @param user - User instance to sign out.
|
|
63
|
+
*/
|
|
45
64
|
async signout(user: User): Promise<any> {
|
|
46
65
|
// Remove all tokens associated with this user
|
|
47
66
|
for (const [token, data] of this.tokens.entries()) {
|
|
@@ -52,6 +71,12 @@ export class MockAuthAdapter extends AbstractAuthAdapter {
|
|
|
52
71
|
return { success: true }
|
|
53
72
|
}
|
|
54
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Mock user state update in memory.
|
|
76
|
+
*
|
|
77
|
+
* @param user - Target user.
|
|
78
|
+
* @param updatable - Property modifications.
|
|
79
|
+
*/
|
|
55
80
|
async update(user: User, updatable: any): Promise<any> {
|
|
56
81
|
const existingUser = this.registeredUsers.get(user._.email)
|
|
57
82
|
if (!existingUser) {
|
|
@@ -64,6 +89,11 @@ export class MockAuthAdapter extends AbstractAuthAdapter {
|
|
|
64
89
|
return { success: true, user: updatedUser }
|
|
65
90
|
}
|
|
66
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Evicts the user and all associated mock tokens from memory.
|
|
94
|
+
*
|
|
95
|
+
* @param user - User instance to delete.
|
|
96
|
+
*/
|
|
67
97
|
async delete(user: User): Promise<any> {
|
|
68
98
|
if (!this.registeredUsers.has(user._.email)) {
|
|
69
99
|
throw new Error('User not found')
|
|
@@ -75,6 +105,11 @@ export class MockAuthAdapter extends AbstractAuthAdapter {
|
|
|
75
105
|
return { success: true }
|
|
76
106
|
}
|
|
77
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Reads the cached token data payload.
|
|
110
|
+
*
|
|
111
|
+
* @param token - Raw mock token string.
|
|
112
|
+
*/
|
|
78
113
|
getAuthToken(token: string): any {
|
|
79
114
|
const tokenData = this.tokens.get(token)
|
|
80
115
|
if (!tokenData) {
|
|
@@ -83,6 +118,11 @@ export class MockAuthAdapter extends AbstractAuthAdapter {
|
|
|
83
118
|
return tokenData
|
|
84
119
|
}
|
|
85
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Cycles an old refresh token for a completely new session pair.
|
|
123
|
+
*
|
|
124
|
+
* @param refreshToken - Active mock refresh token string.
|
|
125
|
+
*/
|
|
86
126
|
async refreshToken(refreshToken: string): Promise<any> {
|
|
87
127
|
const oldToken = this.refreshTokens.get(refreshToken)
|
|
88
128
|
if (!oldToken) {
|
|
@@ -113,6 +153,11 @@ export class MockAuthAdapter extends AbstractAuthAdapter {
|
|
|
113
153
|
}
|
|
114
154
|
}
|
|
115
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Blacklists a specific access token.
|
|
158
|
+
*
|
|
159
|
+
* @param token - Target mock token to drop.
|
|
160
|
+
*/
|
|
116
161
|
revokeAuthToken(token: string): any {
|
|
117
162
|
if (!this.tokens.has(token)) {
|
|
118
163
|
throw new Error('Token not found')
|
|
@@ -134,6 +179,12 @@ export class MockAuthAdapter extends AbstractAuthAdapter {
|
|
|
134
179
|
return { success: true }
|
|
135
180
|
}
|
|
136
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Manually appends structural role claims onto a registered mock user.
|
|
184
|
+
*
|
|
185
|
+
* @param id - Mock user ID.
|
|
186
|
+
* @param claims - Payload to merge.
|
|
187
|
+
*/
|
|
137
188
|
setCustomUserClaims(id: string, claims: any): any {
|
|
138
189
|
// Find user by id and set custom claims
|
|
139
190
|
for (const [email, user] of this.registeredUsers.entries()) {
|
|
@@ -146,16 +197,25 @@ export class MockAuthAdapter extends AbstractAuthAdapter {
|
|
|
146
197
|
}
|
|
147
198
|
|
|
148
199
|
// Helper methods for testing
|
|
200
|
+
/**
|
|
201
|
+
* Test utility: Flushes all internal registers.
|
|
202
|
+
*/
|
|
149
203
|
clearAll(): void {
|
|
150
204
|
this.registeredUsers.clear()
|
|
151
205
|
this.tokens.clear()
|
|
152
206
|
this.refreshTokens.clear()
|
|
153
207
|
}
|
|
154
208
|
|
|
209
|
+
/**
|
|
210
|
+
* Test utility: Retrieves user instance by its stored key (email).
|
|
211
|
+
*/
|
|
155
212
|
getUserByEmail(email: string): User | undefined {
|
|
156
213
|
return this.registeredUsers.get(email)
|
|
157
214
|
}
|
|
158
215
|
|
|
216
|
+
/**
|
|
217
|
+
* Test utility: Asserts the existence of an active token.
|
|
218
|
+
*/
|
|
159
219
|
hasToken(token: string): boolean {
|
|
160
220
|
return this.tokens.has(token)
|
|
161
221
|
}
|