@maestro-js/password 1.0.0-alpha.18 → 1.0.0-alpha.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/index.d.ts +27 -55
- package/dist/index.js +4 -25
- package/package.json +4 -8
package/dist/index.d.ts
CHANGED
|
@@ -4,63 +4,38 @@ import { Hash } from '@maestro-js/hash';
|
|
|
4
4
|
|
|
5
5
|
declare function create<Id, Credentials extends {
|
|
6
6
|
password: string;
|
|
7
|
-
}>(config: Password.
|
|
8
|
-
declare
|
|
9
|
-
|
|
10
|
-
* Password verification and reset with pluggable credential lookups and secure token-based resets.
|
|
11
|
-
* Call methods directly on the default instance, or use `Password.Provider.create()` for named instances.
|
|
12
|
-
*/
|
|
13
|
-
declare const PasswordBase: {
|
|
14
|
-
Provider: {
|
|
15
|
-
create: typeof create;
|
|
16
|
-
register: (name: Password.Provider.Key, item: Password.AnyPasswordService) => void;
|
|
17
|
-
};
|
|
18
|
-
provider: typeof provider;
|
|
7
|
+
}>(config: Password.Config<Id, Credentials>): Password.Service<Id, Credentials>;
|
|
8
|
+
declare const Password: {
|
|
9
|
+
create: typeof create;
|
|
19
10
|
errors: {
|
|
20
11
|
ThrottledError: CustomErrors.CustomErrorConstructor<undefined, {}, "tooManyRequests">;
|
|
21
12
|
InvalidTokenError: CustomErrors.CustomErrorConstructor<undefined, {}, "unprocessableContent">;
|
|
22
13
|
ExpiredTokenError: CustomErrors.CustomErrorConstructor<undefined, {}, "unprocessableContent">;
|
|
23
14
|
};
|
|
24
15
|
};
|
|
25
|
-
type KeysWithFallback = keyof Password.Provider.Keys extends never ? {
|
|
26
|
-
default: {
|
|
27
|
-
Id: unknown;
|
|
28
|
-
Credentials: {
|
|
29
|
-
password: string;
|
|
30
|
-
} & Record<string, unknown>;
|
|
31
|
-
};
|
|
32
|
-
} : Password.Provider.Keys;
|
|
33
|
-
declare const Password: Password.PasswordService<'default'> & typeof PasswordBase;
|
|
34
16
|
declare namespace Password {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}) | null>;
|
|
58
|
-
updatePasswordHash(id: Id, passwordHash: string): Promise<void>;
|
|
59
|
-
updateCredentialsInvalidBefore(id: Id, date: Iso.Instant): Promise<void>;
|
|
60
|
-
/** Used for password hashing and verification. `Hash.drivers.bcrypt()` is recommended. */
|
|
61
|
-
hash: Hash.HashService;
|
|
62
|
-
passwordResetOptions?: Password.ResetOptions<Id>;
|
|
63
|
-
}
|
|
17
|
+
interface Service<Id, Credentials extends {
|
|
18
|
+
password: string;
|
|
19
|
+
}> {
|
|
20
|
+
verifyCredentials(credentials: Credentials): Promise<Password.Authenticatable<Id> | null>;
|
|
21
|
+
createPasswordResetToken: (authenticatableId: Id) => Promise<string>;
|
|
22
|
+
resetPassword: (options: {
|
|
23
|
+
authenticatableId: Id;
|
|
24
|
+
token: string;
|
|
25
|
+
newPassword: string;
|
|
26
|
+
}) => Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
interface Config<Id, Credentials extends {
|
|
29
|
+
password: string;
|
|
30
|
+
}> {
|
|
31
|
+
getAuthenticatableByCredentials(credentials: Omit<Credentials, 'password'>): Promise<(Password.Authenticatable<Id> & {
|
|
32
|
+
passwordHash: string;
|
|
33
|
+
}) | null>;
|
|
34
|
+
updatePasswordHash(id: Id, passwordHash: string): Promise<void>;
|
|
35
|
+
updateCredentialsInvalidBefore(id: Id, date: Iso.Instant): Promise<void>;
|
|
36
|
+
/** Used for password hashing and verification. `Hash.drivers.bcrypt()` is recommended. */
|
|
37
|
+
hash: Hash.HashService;
|
|
38
|
+
passwordResetOptions?: Password.ResetOptions<Id>;
|
|
64
39
|
}
|
|
65
40
|
interface Authenticatable<Id> {
|
|
66
41
|
id: Id;
|
|
@@ -78,14 +53,11 @@ declare namespace Password {
|
|
|
78
53
|
getBySelector(selector: string): Promise<Password.ResetTokenRecord<Id> | null>;
|
|
79
54
|
getByAuthenticatableId(authenticatableId: Id): Promise<Password.ResetTokenRecord<Id> | null>;
|
|
80
55
|
deleteByAuthenticatableId(authenticatableId: Id): Promise<void>;
|
|
56
|
+
/** Token lifetime in minutes. Default: 60 */
|
|
57
|
+
tokenExpirationMinutes?: number;
|
|
81
58
|
/** Minimum seconds between createToken calls for the same authenticatable. Default: 60 */
|
|
82
59
|
throttleSeconds?: number;
|
|
83
60
|
}
|
|
84
|
-
namespace Provider {
|
|
85
|
-
type Key = keyof KeysWithFallback;
|
|
86
|
-
interface Keys {
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
61
|
}
|
|
90
62
|
|
|
91
63
|
export { Password };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import crypto from "crypto";
|
|
3
3
|
import { CustomErrors } from "@maestro-js/custom-errors";
|
|
4
|
-
import { ServiceRegistry } from "@maestro-js/service-registry";
|
|
5
4
|
import { instantFns } from "iso-fns2";
|
|
6
5
|
function create(config) {
|
|
7
6
|
const hashService = config.hash;
|
|
@@ -24,7 +23,7 @@ function create(config) {
|
|
|
24
23
|
}
|
|
25
24
|
return { id: authenticatable.id, credentialsInvalidBefore: authenticatable.credentialsInvalidBefore };
|
|
26
25
|
}
|
|
27
|
-
async function createPasswordResetToken(authenticatableId
|
|
26
|
+
async function createPasswordResetToken(authenticatableId) {
|
|
28
27
|
if (!passwordResetOptions) {
|
|
29
28
|
throw new Error("Password reset is not configured. Provide `passwordResetOptions` when creating the password service.");
|
|
30
29
|
}
|
|
@@ -39,7 +38,7 @@ function create(config) {
|
|
|
39
38
|
const verifier = crypto.randomBytes(32).toString("base64url");
|
|
40
39
|
const verifierHash = await config.hash.hash(verifier);
|
|
41
40
|
const now = instantFns.now();
|
|
42
|
-
const expirationDate = instantFns.add(now, { minutes:
|
|
41
|
+
const expirationDate = instantFns.add(now, { minutes: passwordResetOptions.tokenExpirationMinutes ?? 60 });
|
|
43
42
|
await passwordResetOptions.create({
|
|
44
43
|
authenticatableId,
|
|
45
44
|
selector,
|
|
@@ -86,21 +85,6 @@ function create(config) {
|
|
|
86
85
|
resetPassword
|
|
87
86
|
};
|
|
88
87
|
}
|
|
89
|
-
var registry = ServiceRegistry.createRegistry(
|
|
90
|
-
ServiceRegistry.proxyFunctionsForObject
|
|
91
|
-
);
|
|
92
|
-
var Provider = {
|
|
93
|
-
create,
|
|
94
|
-
register: registry.register
|
|
95
|
-
};
|
|
96
|
-
function provider(key) {
|
|
97
|
-
const service = registry.resolve(key);
|
|
98
|
-
return {
|
|
99
|
-
verifyCredentials: service.verifyCredentials,
|
|
100
|
-
createPasswordResetToken: service.createPasswordResetToken,
|
|
101
|
-
resetPassword: service.resetPassword
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
88
|
var PasswordResetThrottledError = CustomErrors.create({
|
|
105
89
|
name: "PasswordResetThrottledError",
|
|
106
90
|
message: "Password reset requests are being throttled. Please try again later.",
|
|
@@ -116,19 +100,14 @@ var PasswordResetExpiredTokenError = CustomErrors.create({
|
|
|
116
100
|
message: "The password reset token has expired.",
|
|
117
101
|
httpStatusCode: "unprocessableContent"
|
|
118
102
|
});
|
|
119
|
-
var
|
|
120
|
-
|
|
121
|
-
provider,
|
|
103
|
+
var Password = {
|
|
104
|
+
create,
|
|
122
105
|
errors: {
|
|
123
106
|
ThrottledError: PasswordResetThrottledError,
|
|
124
107
|
InvalidTokenError: PasswordResetInvalidTokenError,
|
|
125
108
|
ExpiredTokenError: PasswordResetExpiredTokenError
|
|
126
109
|
}
|
|
127
110
|
};
|
|
128
|
-
var Password = {
|
|
129
|
-
...PasswordBase,
|
|
130
|
-
...provider("default")
|
|
131
|
-
};
|
|
132
111
|
function decodePasswordResetToken(token) {
|
|
133
112
|
const [selector, verifier] = token.split("|");
|
|
134
113
|
if (!selector || !verifier) return null;
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"default": "./dist/index.js"
|
|
8
8
|
}
|
|
9
9
|
},
|
|
10
|
-
"version": "1.0.0-alpha.
|
|
10
|
+
"version": "1.0.0-alpha.2",
|
|
11
11
|
"publishConfig": {
|
|
12
12
|
"access": "restricted"
|
|
13
13
|
},
|
|
@@ -16,15 +16,11 @@
|
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"iso-fns2": "npm:iso-fns@2.0.0-alpha.26",
|
|
19
|
-
"@maestro-js/
|
|
20
|
-
"@maestro-js/
|
|
21
|
-
},
|
|
22
|
-
"peerDependencies": {
|
|
23
|
-
"@maestro-js/hash": "1.0.0-alpha.18"
|
|
19
|
+
"@maestro-js/custom-errors": "1.0.0-alpha.2",
|
|
20
|
+
"@maestro-js/hash": "1.0.0-alpha.2"
|
|
24
21
|
},
|
|
25
22
|
"devDependencies": {
|
|
26
|
-
"@types/node": "^22.19.11"
|
|
27
|
-
"@maestro-js/hash": "1.0.0-alpha.18"
|
|
23
|
+
"@types/node": "^22.19.11"
|
|
28
24
|
},
|
|
29
25
|
"license": "UNLICENSED",
|
|
30
26
|
"engines": {
|