@tstdl/base 0.83.3 → 0.83.5
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/authentication/server/authentication.service.d.ts +10 -2
- package/authentication/server/authentication.service.js +18 -7
- package/authentication/server/module.d.ts +2 -1
- package/authentication/server/module.js +1 -1
- package/container/provider.d.ts +5 -4
- package/container/provider.js +13 -8
- package/package.json +1 -1
- package/utils/cryptography.d.ts +10 -4
- package/utils/cryptography.js +6 -1
- package/utils/type-guards.d.ts +6 -0
- package/utils/type-guards.js +26 -0
|
@@ -9,8 +9,15 @@ import { AuthenticationSessionRepository } from './authentication-session.reposi
|
|
|
9
9
|
import { AuthenticationSubjectResolver } from './authentication-subject.resolver.js';
|
|
10
10
|
import { AuthenticationTokenPayloadProvider } from './authentication-token-payload.provider.js';
|
|
11
11
|
export declare class AuthenticationServiceOptions {
|
|
12
|
-
/**
|
|
13
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Secrets used for signing tokens and refreshTokens
|
|
14
|
+
* If single secret is provided, multiple secrets are derived internally
|
|
15
|
+
*/
|
|
16
|
+
secret: string | BinaryData | {
|
|
17
|
+
tokenSigningSecret: Uint8Array;
|
|
18
|
+
refreshTokenSigningSecret: Uint8Array;
|
|
19
|
+
secretResetTokenSigningSecret: Uint8Array;
|
|
20
|
+
};
|
|
14
21
|
/** Token version, forces refresh on mismatch (useful if payload changes) */
|
|
15
22
|
version?: number;
|
|
16
23
|
/** How long a token is valid */
|
|
@@ -39,6 +46,7 @@ export declare class AuthenticationService<AdditionalTokenPayload = Record<never
|
|
|
39
46
|
private readonly tokenPayloadProvider;
|
|
40
47
|
private readonly subjectResolver;
|
|
41
48
|
private readonly authenticationResetSecretHandler;
|
|
49
|
+
private readonly options;
|
|
42
50
|
private readonly secret;
|
|
43
51
|
private readonly tokenVersion;
|
|
44
52
|
private readonly tokenTimeToLive;
|
|
@@ -60,7 +60,10 @@ var __param = function(paramIndex, decorator) {
|
|
|
60
60
|
};
|
|
61
61
|
};
|
|
62
62
|
class AuthenticationServiceOptions {
|
|
63
|
-
/**
|
|
63
|
+
/**
|
|
64
|
+
* Secrets used for signing tokens and refreshTokens
|
|
65
|
+
* If single secret is provided, multiple secrets are derived internally
|
|
66
|
+
*/
|
|
64
67
|
secret;
|
|
65
68
|
/** Token version, forces refresh on mismatch (useful if payload changes) */
|
|
66
69
|
version;
|
|
@@ -71,7 +74,7 @@ class AuthenticationServiceOptions {
|
|
|
71
74
|
/** How long a secret reset token is valid. */
|
|
72
75
|
secretResetTokenTimeToLive;
|
|
73
76
|
}
|
|
74
|
-
const SIGNING_SECRETS_LENGTH =
|
|
77
|
+
const SIGNING_SECRETS_LENGTH = 64;
|
|
75
78
|
let AuthenticationService = class AuthenticationService2 {
|
|
76
79
|
credentialsRepository;
|
|
77
80
|
sessionRepository;
|
|
@@ -79,6 +82,7 @@ let AuthenticationService = class AuthenticationService2 {
|
|
|
79
82
|
tokenPayloadProvider;
|
|
80
83
|
subjectResolver;
|
|
81
84
|
authenticationResetSecretHandler;
|
|
85
|
+
options;
|
|
82
86
|
secret;
|
|
83
87
|
tokenVersion;
|
|
84
88
|
tokenTimeToLive;
|
|
@@ -94,7 +98,7 @@ let AuthenticationService = class AuthenticationService2 {
|
|
|
94
98
|
this.subjectResolver = subjectResolver;
|
|
95
99
|
this.tokenPayloadProvider = tokenPayloadProvider;
|
|
96
100
|
this.authenticationResetSecretHandler = authenticationResetSecretHandler;
|
|
97
|
-
this.
|
|
101
|
+
this.options = options;
|
|
98
102
|
this.tokenVersion = options.version ?? 1;
|
|
99
103
|
this.tokenTimeToLive = options.tokenTimeToLive ?? 5 * import_units.millisecondsPerMinute;
|
|
100
104
|
this.refreshTokenTimeToLive = options.refreshTokenTimeToLive ?? 5 * import_units.millisecondsPerDay;
|
|
@@ -104,7 +108,13 @@ let AuthenticationService = class AuthenticationService2 {
|
|
|
104
108
|
await this.initialize();
|
|
105
109
|
}
|
|
106
110
|
async initialize() {
|
|
107
|
-
|
|
111
|
+
if ((0, import_type_guards.isString)(this.options.secret) || (0, import_type_guards.isBinaryData)(this.options.secret)) {
|
|
112
|
+
await this.deriveSigningSecrets(this.options.secret);
|
|
113
|
+
} else {
|
|
114
|
+
this.derivedTokenSigningSecret = this.options.secret.tokenSigningSecret;
|
|
115
|
+
this.derivedRefreshTokenSigningSecret = this.options.secret.refreshTokenSigningSecret;
|
|
116
|
+
this.derivedSecretResetTokenSigningSecret = this.options.secret.secretResetTokenSigningSecret;
|
|
117
|
+
}
|
|
108
118
|
}
|
|
109
119
|
async setCredentials(subject, secret) {
|
|
110
120
|
const actualSubject = await this.resolveSubject(subject);
|
|
@@ -269,9 +279,10 @@ let AuthenticationService = class AuthenticationService2 {
|
|
|
269
279
|
const token = await (0, import_jwt.createJwtTokenString)(jsonToken, this.derivedSecretResetTokenSigningSecret);
|
|
270
280
|
return { token, jsonToken };
|
|
271
281
|
}
|
|
272
|
-
async deriveSigningSecrets() {
|
|
273
|
-
const key = await (0, import_cryptography.importPbkdf2Key)(
|
|
274
|
-
const
|
|
282
|
+
async deriveSigningSecrets(secret) {
|
|
283
|
+
const key = await (0, import_cryptography.importPbkdf2Key)(secret);
|
|
284
|
+
const algorithm = { name: "PBKDF2", hash: "SHA-512", iterations: 5e5, salt: new Uint8Array() };
|
|
285
|
+
const [derivedTokenSigningSecret, derivedRefreshTokenSigningSecret, derivedSecretResetTokenSigningSecret] = await (0, import_cryptography.deriveBytesMultiple)(algorithm, key, 3, SIGNING_SECRETS_LENGTH);
|
|
275
286
|
this.derivedTokenSigningSecret = derivedTokenSigningSecret;
|
|
276
287
|
this.derivedRefreshTokenSigningSecret = derivedRefreshTokenSigningSecret;
|
|
277
288
|
this.derivedSecretResetTokenSigningSecret = derivedSecretResetTokenSigningSecret;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Provider } from '../../container/index.js';
|
|
1
2
|
import type { Type } from '../../types.js';
|
|
2
3
|
import { AuthenticationCredentialsRepository } from './authentication-credentials.repository.js';
|
|
3
4
|
import { AuthenticationSessionRepository } from './authentication-session.repository.js';
|
|
@@ -5,7 +6,7 @@ import { AuthenticationSubjectResolver } from './authentication-subject.resolver
|
|
|
5
6
|
import { AuthenticationTokenPayloadProvider } from './authentication-token-payload.provider.js';
|
|
6
7
|
import { AuthenticationService, AuthenticationServiceOptions } from './authentication.service.js';
|
|
7
8
|
export type AuthenticationModuleConfig = {
|
|
8
|
-
serviceOptions: AuthenticationServiceOptions
|
|
9
|
+
serviceOptions: AuthenticationServiceOptions | Provider<AuthenticationServiceOptions>;
|
|
9
10
|
credentialsRepository: Type<AuthenticationCredentialsRepository>;
|
|
10
11
|
sessionRepository: Type<AuthenticationSessionRepository>;
|
|
11
12
|
/** override default AuthenticationService */
|
|
@@ -29,7 +29,7 @@ var import_authentication_subject_resolver = require("./authentication-subject.r
|
|
|
29
29
|
var import_authentication_token_payload_provider = require("./authentication-token-payload.provider.js");
|
|
30
30
|
var import_authentication_service = require("./authentication.service.js");
|
|
31
31
|
function configureAuthenticationServer(config) {
|
|
32
|
-
import_container.container.register(import_authentication_service.AuthenticationServiceOptions, { useValue: config.serviceOptions });
|
|
32
|
+
import_container.container.register(import_authentication_service.AuthenticationServiceOptions, (0, import_container.isProvider)(config.serviceOptions) ? config.serviceOptions : { useValue: config.serviceOptions });
|
|
33
33
|
import_container.container.registerSingleton(import_authentication_credentials_repository.AuthenticationCredentialsRepository, { useToken: config.credentialsRepository });
|
|
34
34
|
import_container.container.registerSingleton(import_authentication_session_repository.AuthenticationSessionRepository, { useToken: config.sessionRepository });
|
|
35
35
|
if ((0, import_type_guards.isDefined)(config.authenticationService)) {
|
package/container/provider.d.ts
CHANGED
|
@@ -28,7 +28,8 @@ export declare function classProvider<T>(constructor: Constructor<T>): ClassProv
|
|
|
28
28
|
export declare function valueProvider<T>(value: T): ValueProvider<T>;
|
|
29
29
|
export declare function tokenProvider<T, A>(token: InjectionToken<T, A>, argument?: InjectableArgument<T, A>): TokenProvider<T>;
|
|
30
30
|
export declare function factoryProvider<T, A>(factory: Factory<T, A>): FactoryProvider<T, A>;
|
|
31
|
-
export declare function isClassProvider<T>(
|
|
32
|
-
export declare function isValueProvider<T>(
|
|
33
|
-
export declare function isTokenProvider<T>(
|
|
34
|
-
export declare function isFactoryProvider<T, A>(
|
|
31
|
+
export declare function isClassProvider<T>(value: unknown): value is ClassProvider<T>;
|
|
32
|
+
export declare function isValueProvider<T>(value: unknown): value is ValueProvider<T>;
|
|
33
|
+
export declare function isTokenProvider<T>(value: unknown): value is TokenProvider<T>;
|
|
34
|
+
export declare function isFactoryProvider<T, A>(value: unknown): value is FactoryProvider<T, A>;
|
|
35
|
+
export declare function isProvider<T, A>(value: unknown): value is Provider<T, A>;
|
package/container/provider.js
CHANGED
|
@@ -22,6 +22,7 @@ __export(provider_exports, {
|
|
|
22
22
|
factoryProvider: () => factoryProvider,
|
|
23
23
|
isClassProvider: () => isClassProvider,
|
|
24
24
|
isFactoryProvider: () => isFactoryProvider,
|
|
25
|
+
isProvider: () => isProvider,
|
|
25
26
|
isTokenProvider: () => isTokenProvider,
|
|
26
27
|
isValueProvider: () => isValueProvider,
|
|
27
28
|
tokenProvider: () => tokenProvider,
|
|
@@ -29,6 +30,7 @@ __export(provider_exports, {
|
|
|
29
30
|
});
|
|
30
31
|
module.exports = __toCommonJS(provider_exports);
|
|
31
32
|
var import_object = require("../utils/object/object.js");
|
|
33
|
+
var import_type_guards = require("../utils/type-guards.js");
|
|
32
34
|
function classProvider(constructor) {
|
|
33
35
|
return { useClass: constructor };
|
|
34
36
|
}
|
|
@@ -41,15 +43,18 @@ function tokenProvider(token, argument) {
|
|
|
41
43
|
function factoryProvider(factory) {
|
|
42
44
|
return { useFactory: factory };
|
|
43
45
|
}
|
|
44
|
-
function isClassProvider(
|
|
45
|
-
return (0, import_object.hasOwnProperty)(
|
|
46
|
+
function isClassProvider(value) {
|
|
47
|
+
return (0, import_type_guards.isObject)(value) && (0, import_object.hasOwnProperty)(value, "useClass");
|
|
46
48
|
}
|
|
47
|
-
function isValueProvider(
|
|
48
|
-
return (0, import_object.hasOwnProperty)(
|
|
49
|
+
function isValueProvider(value) {
|
|
50
|
+
return (0, import_type_guards.isObject)(value) && (0, import_object.hasOwnProperty)(value, "useValue");
|
|
49
51
|
}
|
|
50
|
-
function isTokenProvider(
|
|
51
|
-
return (0, import_object.hasOwnProperty)(
|
|
52
|
+
function isTokenProvider(value) {
|
|
53
|
+
return (0, import_type_guards.isObject)(value) && ((0, import_object.hasOwnProperty)(value, "useToken") || (0, import_object.hasOwnProperty)(value, "useTokenProvider"));
|
|
52
54
|
}
|
|
53
|
-
function isFactoryProvider(
|
|
54
|
-
return (0, import_object.hasOwnProperty)(
|
|
55
|
+
function isFactoryProvider(value) {
|
|
56
|
+
return (0, import_type_guards.isObject)(value) && (0, import_object.hasOwnProperty)(value, "useFactory");
|
|
57
|
+
}
|
|
58
|
+
function isProvider(value) {
|
|
59
|
+
return (0, import_type_guards.isObject)(value) && (isClassProvider(value) || isValueProvider(value) || isTokenProvider(value) || isFactoryProvider(value));
|
|
55
60
|
}
|
package/package.json
CHANGED
package/utils/cryptography.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export type AsymmetricAlgorithm = 'RSASSA-PKCS1-v1_5' | 'RSA-PSS' | 'RSA-OAEP' |
|
|
|
8
8
|
export type CryptionAlgorithm = Parameters<typeof crypto.subtle.encrypt>[0];
|
|
9
9
|
export type SignAlgorithm = Parameters<typeof crypto.subtle.sign>[0];
|
|
10
10
|
export type KeyAlgorithm = Parameters<typeof crypto.subtle.generateKey>[0];
|
|
11
|
+
export type DeriveAlgorithm = Parameters<typeof globalThis.crypto.subtle.deriveBits>['0'];
|
|
11
12
|
export type KeyType = 'raw' | 'pkcs8' | 'spki' | 'jwk';
|
|
12
13
|
export type Key = JsonWebKey | BinaryData;
|
|
13
14
|
export type ScryptOptions = {
|
|
@@ -105,13 +106,18 @@ export declare function generateEcdsaKey(curve: EcdsaCurve, extractable?: boolea
|
|
|
105
106
|
* @param extractable whether the key can be used for exportKey
|
|
106
107
|
*/
|
|
107
108
|
export declare function generatePbkdf2Key(extractable?: boolean): Promise<CryptoKey>;
|
|
108
|
-
type AlgorithmParameter = Parameters<typeof globalThis.crypto.subtle.deriveBits>['0'];
|
|
109
109
|
/**
|
|
110
|
-
* derive
|
|
110
|
+
* derive byte array from key
|
|
111
|
+
* @param length length in bytes
|
|
112
|
+
* @param algorithm algorithm to derive with
|
|
113
|
+
* @param baseKey key to derive from
|
|
114
|
+
*/
|
|
115
|
+
export declare function deriveBytes(algorithm: DeriveAlgorithm, baseKey: CryptoKey, length: number): Promise<Uint8Array>;
|
|
116
|
+
/**
|
|
117
|
+
* derive multiply byte arrays from key
|
|
111
118
|
* @param count how many Uint8Arrays to dervice
|
|
112
119
|
* @param length length of each Uint8Array in bytes
|
|
113
120
|
* @param algorithm algorithm to derive with
|
|
114
121
|
* @param baseKey key to derive from
|
|
115
122
|
*/
|
|
116
|
-
export declare function deriveBytesMultiple<C extends number>(
|
|
117
|
-
export {};
|
|
123
|
+
export declare function deriveBytesMultiple<C extends number>(algorithm: DeriveAlgorithm, baseKey: CryptoKey, count: C, length: number): Promise<ReadonlyTuple<Uint8Array, C>>;
|
package/utils/cryptography.js
CHANGED
|
@@ -19,6 +19,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var cryptography_exports = {};
|
|
20
20
|
__export(cryptography_exports, {
|
|
21
21
|
decrypt: () => decrypt,
|
|
22
|
+
deriveBytes: () => deriveBytes,
|
|
22
23
|
deriveBytesMultiple: () => deriveBytesMultiple,
|
|
23
24
|
digest: () => digest,
|
|
24
25
|
encrypt: () => encrypt,
|
|
@@ -122,7 +123,11 @@ async function generatePbkdf2Key(extractable = false) {
|
|
|
122
123
|
const key = (0, import_random.getRandomBytes)(16);
|
|
123
124
|
return importPbkdf2Key(key, extractable);
|
|
124
125
|
}
|
|
125
|
-
async function
|
|
126
|
+
async function deriveBytes(algorithm, baseKey, length) {
|
|
127
|
+
const bytes = await globalThis.crypto.subtle.deriveBits(algorithm, baseKey, length * 8);
|
|
128
|
+
return new Uint8Array(bytes);
|
|
129
|
+
}
|
|
130
|
+
async function deriveBytesMultiple(algorithm, baseKey, count, length) {
|
|
126
131
|
const totalBits = count * length * 8;
|
|
127
132
|
const bytes = await globalThis.crypto.subtle.deriveBits(algorithm, baseKey, totalBits);
|
|
128
133
|
return (0, import_array.createArray)(count, (index) => new Uint8Array(bytes.slice(index * length, index * length + length)));
|
package/utils/type-guards.d.ts
CHANGED
|
@@ -118,6 +118,12 @@ export declare function assertBlob(value: any, message?: AssertionMessage): asse
|
|
|
118
118
|
export declare function assertNotBlob<T>(value: T, message?: AssertionMessage): asserts value is InferIsNotType<T, typeof isBlob>;
|
|
119
119
|
export declare function assertBlobPass(value: any, message?: AssertionMessage): InferIsType<typeof isBlob>;
|
|
120
120
|
export declare function assertNotBlobPass<T>(value: T, message?: AssertionMessage): InferIsNotType<T, typeof isBlob>;
|
|
121
|
+
export declare function isBinaryData(value: any): value is BinaryData;
|
|
122
|
+
export declare function isNotBinaryData<T>(value: T): value is InferIsNotType<T, typeof isBinaryData>;
|
|
123
|
+
export declare function assertBinaryData(value: any, message?: AssertionMessage): asserts value is InferIsType<typeof isBinaryData>;
|
|
124
|
+
export declare function assertNotBinaryData<T>(value: T, message?: AssertionMessage): asserts value is InferIsNotType<T, typeof isBinaryData>;
|
|
125
|
+
export declare function assertBinaryDataPass(value: any, message?: AssertionMessage): InferIsType<typeof isBinaryData>;
|
|
126
|
+
export declare function assertNotBinaryDataPass<T>(value: T, message?: AssertionMessage): InferIsNotType<T, typeof isBinaryData>;
|
|
121
127
|
export declare function isArrayBuffer(value: any): value is ArrayBuffer;
|
|
122
128
|
export declare function isNotArrayBuffer<T>(value: T): value is InferIsNotType<T, typeof isArrayBuffer>;
|
|
123
129
|
export declare function assertArrayBuffer(value: any, message?: AssertionMessage): asserts value is InferIsType<typeof isArrayBuffer>;
|
package/utils/type-guards.js
CHANGED
|
@@ -31,6 +31,8 @@ __export(type_guards_exports, {
|
|
|
31
31
|
assertBigIntPass: () => assertBigIntPass,
|
|
32
32
|
assertBigUint64Array: () => assertBigUint64Array,
|
|
33
33
|
assertBigUint64ArrayPass: () => assertBigUint64ArrayPass,
|
|
34
|
+
assertBinaryData: () => assertBinaryData,
|
|
35
|
+
assertBinaryDataPass: () => assertBinaryDataPass,
|
|
34
36
|
assertBlob: () => assertBlob,
|
|
35
37
|
assertBlobPass: () => assertBlobPass,
|
|
36
38
|
assertBoolean: () => assertBoolean,
|
|
@@ -70,6 +72,8 @@ __export(type_guards_exports, {
|
|
|
70
72
|
assertNotBigIntPass: () => assertNotBigIntPass,
|
|
71
73
|
assertNotBigUint64Array: () => assertNotBigUint64Array,
|
|
72
74
|
assertNotBigUint64ArrayPass: () => assertNotBigUint64ArrayPass,
|
|
75
|
+
assertNotBinaryData: () => assertNotBinaryData,
|
|
76
|
+
assertNotBinaryDataPass: () => assertNotBinaryDataPass,
|
|
73
77
|
assertNotBlob: () => assertNotBlob,
|
|
74
78
|
assertNotBlobPass: () => assertNotBlobPass,
|
|
75
79
|
assertNotBoolean: () => assertNotBoolean,
|
|
@@ -178,6 +182,7 @@ __export(type_guards_exports, {
|
|
|
178
182
|
isBigInt: () => isBigInt,
|
|
179
183
|
isBigInt64Array: () => isBigInt64Array,
|
|
180
184
|
isBigUint64Array: () => isBigUint64Array,
|
|
185
|
+
isBinaryData: () => isBinaryData,
|
|
181
186
|
isBlob: () => isBlob,
|
|
182
187
|
isBoolean: () => isBoolean,
|
|
183
188
|
isDataView: () => isDataView,
|
|
@@ -197,6 +202,7 @@ __export(type_guards_exports, {
|
|
|
197
202
|
isNotBigInt: () => isNotBigInt,
|
|
198
203
|
isNotBigInt64Array: () => isNotBigInt64Array,
|
|
199
204
|
isNotBigUint64Array: () => isNotBigUint64Array,
|
|
205
|
+
isNotBinaryData: () => isNotBinaryData,
|
|
200
206
|
isNotBlob: () => isNotBlob,
|
|
201
207
|
isNotBoolean: () => isNotBoolean,
|
|
202
208
|
isNotDataView: () => isNotDataView,
|
|
@@ -642,6 +648,26 @@ function assertNotBlobPass(value, message) {
|
|
|
642
648
|
assertNotBlob(value, message);
|
|
643
649
|
return value;
|
|
644
650
|
}
|
|
651
|
+
function isBinaryData(value) {
|
|
652
|
+
return isArrayBuffer(value) || isArrayBufferView(value);
|
|
653
|
+
}
|
|
654
|
+
function isNotBinaryData(value) {
|
|
655
|
+
return !isBinaryData(value);
|
|
656
|
+
}
|
|
657
|
+
function assertBinaryData(value, message = "Expected value to be BinaryData.") {
|
|
658
|
+
assert(isBinaryData(value), message);
|
|
659
|
+
}
|
|
660
|
+
function assertNotBinaryData(value, message = "Expected value to not be BinaryData.") {
|
|
661
|
+
assert(isNotBinaryData(value), message);
|
|
662
|
+
}
|
|
663
|
+
function assertBinaryDataPass(value, message) {
|
|
664
|
+
assertBinaryData(value, message);
|
|
665
|
+
return value;
|
|
666
|
+
}
|
|
667
|
+
function assertNotBinaryDataPass(value, message) {
|
|
668
|
+
assertNotBinaryData(value, message);
|
|
669
|
+
return value;
|
|
670
|
+
}
|
|
645
671
|
function isArrayBuffer(value) {
|
|
646
672
|
return value instanceof ArrayBuffer;
|
|
647
673
|
}
|