@tstdl/base 0.93.83 → 0.93.85
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/models/authentication-credentials.model.d.ts +1 -1
- package/authentication/models/authentication-credentials.model.js +3 -3
- package/authentication/models/authentication-session.model.d.ts +1 -1
- package/authentication/models/authentication-session.model.js +2 -2
- package/authentication/server/authentication.service.js +11 -11
- package/authentication/server/drizzle/{0000_majestic_proudstar.sql → 0000_normal_paper_doll.sql} +5 -5
- package/authentication/server/drizzle/meta/0000_snapshot.json +10 -10
- package/authentication/server/drizzle/meta/_journal.json +2 -2
- package/package.json +3 -1
|
@@ -11,7 +11,7 @@ import { Table, TenantEntity, TenantReference, Unique, UuidProperty } from '../.
|
|
|
11
11
|
import { Integer, Uint8ArrayProperty } from '../../schema/index.js';
|
|
12
12
|
import { Subject } from './subject.model.js';
|
|
13
13
|
let AuthenticationCredentials = class AuthenticationCredentials extends TenantEntity {
|
|
14
|
-
|
|
14
|
+
subjectId;
|
|
15
15
|
hashVersion;
|
|
16
16
|
/**
|
|
17
17
|
* The salt used to hash the secret.
|
|
@@ -26,7 +26,7 @@ __decorate([
|
|
|
26
26
|
TenantReference(() => Subject),
|
|
27
27
|
UuidProperty(),
|
|
28
28
|
__metadata("design:type", String)
|
|
29
|
-
], AuthenticationCredentials.prototype, "
|
|
29
|
+
], AuthenticationCredentials.prototype, "subjectId", void 0);
|
|
30
30
|
__decorate([
|
|
31
31
|
Integer(),
|
|
32
32
|
__metadata("design:type", Number)
|
|
@@ -41,6 +41,6 @@ __decorate([
|
|
|
41
41
|
], AuthenticationCredentials.prototype, "hash", void 0);
|
|
42
42
|
AuthenticationCredentials = __decorate([
|
|
43
43
|
Table('credentials', { schema: 'authentication' }),
|
|
44
|
-
Unique(['tenantId', '
|
|
44
|
+
Unique(['tenantId', 'subjectId'])
|
|
45
45
|
], AuthenticationCredentials);
|
|
46
46
|
export { AuthenticationCredentials };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Timestamp, Uuid } from '../../orm/index.js';
|
|
2
2
|
import { TenantEntity } from '../../orm/index.js';
|
|
3
3
|
export declare class AuthenticationSession extends TenantEntity {
|
|
4
|
-
|
|
4
|
+
subjectId: Uuid;
|
|
5
5
|
begin: Timestamp;
|
|
6
6
|
end: Timestamp;
|
|
7
7
|
refreshTokenHashVersion: number;
|
|
@@ -11,7 +11,7 @@ import { Table, TenantEntity, TenantReference, TimestampProperty, UuidProperty }
|
|
|
11
11
|
import { Integer, Uint8ArrayProperty } from '../../schema/index.js';
|
|
12
12
|
import { Subject } from './subject.model.js';
|
|
13
13
|
let AuthenticationSession = class AuthenticationSession extends TenantEntity {
|
|
14
|
-
|
|
14
|
+
subjectId;
|
|
15
15
|
begin;
|
|
16
16
|
end;
|
|
17
17
|
refreshTokenHashVersion;
|
|
@@ -28,7 +28,7 @@ __decorate([
|
|
|
28
28
|
TenantReference(() => Subject),
|
|
29
29
|
UuidProperty(),
|
|
30
30
|
__metadata("design:type", String)
|
|
31
|
-
], AuthenticationSession.prototype, "
|
|
31
|
+
], AuthenticationSession.prototype, "subjectId", void 0);
|
|
32
32
|
__decorate([
|
|
33
33
|
TimestampProperty(),
|
|
34
34
|
__metadata("design:type", Number)
|
|
@@ -139,15 +139,15 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
139
139
|
const salt = getRandomBytes(32);
|
|
140
140
|
const hash = await this.getHash(secret, salt);
|
|
141
141
|
await this.#credentialsRepository.transaction(async (tx) => {
|
|
142
|
-
await this.#credentialsRepository.withTransaction(tx).upsert('
|
|
142
|
+
await this.#credentialsRepository.withTransaction(tx).upsert(['tenantId', 'subjectId'], {
|
|
143
143
|
tenantId: subject.tenantId,
|
|
144
|
-
|
|
144
|
+
subjectId: subject.id,
|
|
145
145
|
hashVersion: 1,
|
|
146
146
|
salt,
|
|
147
147
|
hash,
|
|
148
148
|
});
|
|
149
149
|
if (options?.skipSessionInvalidation != true) {
|
|
150
|
-
await this.#sessionRepository.withTransaction(tx).updateManyByQuery({ tenantId: subject.tenantId,
|
|
150
|
+
await this.#sessionRepository.withTransaction(tx).updateManyByQuery({ tenantId: subject.tenantId, subjectId: subject.id }, { end: currentTimestamp() });
|
|
151
151
|
}
|
|
152
152
|
});
|
|
153
153
|
}
|
|
@@ -162,8 +162,8 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
162
162
|
// Always try to load credentials, even if the subject is not resolved, to reduce information leakage.
|
|
163
163
|
// If the subject is not resolved, we will create a new credentials entry with an empty salt and hash.
|
|
164
164
|
// This way, we do not leak if the subject exists or not via timing attacks.
|
|
165
|
-
const credentials = await this.#credentialsRepository.tryLoadByQuery({ tenantId: actualSubject?.tenantId ?? NIL_UUID,
|
|
166
|
-
?? {
|
|
165
|
+
const credentials = await this.#credentialsRepository.tryLoadByQuery({ tenantId: actualSubject?.tenantId ?? NIL_UUID, subjectId: actualSubject?.id ?? NIL_UUID })
|
|
166
|
+
?? { subjectId: actualSubject, salt: new Uint8Array(), hash: new Uint8Array() };
|
|
167
167
|
const hash = await this.getHash(secret, credentials.salt);
|
|
168
168
|
const valid = timingSafeBinaryEquals(hash, credentials.hash);
|
|
169
169
|
if (valid) {
|
|
@@ -184,7 +184,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
184
184
|
return await this.#sessionRepository.transaction(async (tx) => {
|
|
185
185
|
const session = await this.#sessionRepository.withTransaction(tx).insert({
|
|
186
186
|
tenantId: subject.tenantId,
|
|
187
|
-
|
|
187
|
+
subjectId: subject.id,
|
|
188
188
|
begin: now,
|
|
189
189
|
end,
|
|
190
190
|
refreshTokenHashVersion: 0,
|
|
@@ -255,9 +255,9 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
255
255
|
await this.#sessionRepository.update(sessionId, { end: now });
|
|
256
256
|
await authAuditor.info('logout', {
|
|
257
257
|
tenantId: session.tenantId,
|
|
258
|
-
actor: session.
|
|
258
|
+
actor: session.subjectId,
|
|
259
259
|
actorType: ActorType.User,
|
|
260
|
-
targetId: session.
|
|
260
|
+
targetId: session.subjectId,
|
|
261
261
|
targetType: 'User',
|
|
262
262
|
details: { sessionId },
|
|
263
263
|
});
|
|
@@ -287,7 +287,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
287
287
|
const now = currentTimestamp();
|
|
288
288
|
const impersonator = (options.omitImpersonator == true) ? undefined : validatedRefreshToken.payload.impersonator;
|
|
289
289
|
const newEnd = now + this.refreshTokenTimeToLive;
|
|
290
|
-
const subject = await this.#subjectRepository.loadByQuery({ tenantId: session.tenantId, id: session.
|
|
290
|
+
const subject = await this.#subjectRepository.loadByQuery({ tenantId: session.tenantId, id: session.subjectId });
|
|
291
291
|
const tokenPayload = await this.#authenticationAncillaryService?.getTokenPayload(subject, authenticationData, { action: GetTokenPayloadContextAction.Refresh });
|
|
292
292
|
const { token, jsonToken } = await this.createToken({ additionalTokenPayload: tokenPayload, subject, sessionId, refreshTokenExpiration: newEnd, impersonator, timestamp: now });
|
|
293
293
|
const newRefreshToken = await this.createRefreshToken(subject, sessionId, newEnd, { impersonator });
|
|
@@ -299,9 +299,9 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
299
299
|
});
|
|
300
300
|
await authAuditor.info('refresh-success', {
|
|
301
301
|
tenantId: session.tenantId,
|
|
302
|
-
actor: session.
|
|
302
|
+
actor: session.subjectId,
|
|
303
303
|
actorType: ActorType.User,
|
|
304
|
-
targetId: session.
|
|
304
|
+
targetId: session.subjectId,
|
|
305
305
|
targetType: 'User',
|
|
306
306
|
details: { sessionId },
|
|
307
307
|
});
|
package/authentication/server/drizzle/{0000_majestic_proudstar.sql → 0000_normal_paper_doll.sql}
RENAMED
|
@@ -3,7 +3,7 @@ CREATE TYPE "authentication"."user_status" AS ENUM('active', 'suspended', 'pendi
|
|
|
3
3
|
CREATE TABLE "authentication"."credentials" (
|
|
4
4
|
"id" uuid DEFAULT gen_random_uuid() NOT NULL,
|
|
5
5
|
"tenant_id" uuid NOT NULL,
|
|
6
|
-
"
|
|
6
|
+
"subject_id" uuid NOT NULL,
|
|
7
7
|
"hash_version" integer NOT NULL,
|
|
8
8
|
"salt" "bytea" NOT NULL,
|
|
9
9
|
"hash" "bytea" NOT NULL,
|
|
@@ -13,13 +13,13 @@ CREATE TABLE "authentication"."credentials" (
|
|
|
13
13
|
"delete_timestamp" timestamp with time zone,
|
|
14
14
|
"attributes" jsonb DEFAULT '{}'::jsonb NOT NULL,
|
|
15
15
|
CONSTRAINT "credentials_tenant_id_id_pk" PRIMARY KEY("tenant_id","id"),
|
|
16
|
-
CONSTRAINT "
|
|
16
|
+
CONSTRAINT "credentials_tenant_id_subject_id_unique" UNIQUE("tenant_id","subject_id")
|
|
17
17
|
);
|
|
18
18
|
--> statement-breakpoint
|
|
19
19
|
CREATE TABLE "authentication"."session" (
|
|
20
20
|
"id" uuid DEFAULT gen_random_uuid() NOT NULL,
|
|
21
21
|
"tenant_id" uuid NOT NULL,
|
|
22
|
-
"
|
|
22
|
+
"subject_id" uuid NOT NULL,
|
|
23
23
|
"begin" timestamp with time zone NOT NULL,
|
|
24
24
|
"end" timestamp with time zone NOT NULL,
|
|
25
25
|
"refresh_token_hash_version" integer NOT NULL,
|
|
@@ -96,8 +96,8 @@ CREATE TABLE "authentication"."user" (
|
|
|
96
96
|
CONSTRAINT "user_tenant_id_email_unique" UNIQUE("tenant_id","email")
|
|
97
97
|
);
|
|
98
98
|
--> statement-breakpoint
|
|
99
|
-
ALTER TABLE "authentication"."credentials" ADD CONSTRAINT "credentials_id_subject_fkey" FOREIGN KEY ("tenant_id","
|
|
100
|
-
ALTER TABLE "authentication"."session" ADD CONSTRAINT "session_id_subject_fkey" FOREIGN KEY ("tenant_id","
|
|
99
|
+
ALTER TABLE "authentication"."credentials" ADD CONSTRAINT "credentials_id_subject_fkey" FOREIGN KEY ("tenant_id","subject_id") REFERENCES "authentication"."subject"("tenant_id","id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
100
|
+
ALTER TABLE "authentication"."session" ADD CONSTRAINT "session_id_subject_fkey" FOREIGN KEY ("tenant_id","subject_id") REFERENCES "authentication"."subject"("tenant_id","id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
101
101
|
ALTER TABLE "authentication"."service_account" ADD CONSTRAINT "service_account_id_subject_fkey" FOREIGN KEY ("tenant_id","parent") REFERENCES "authentication"."subject"("tenant_id","id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
102
102
|
ALTER TABLE "authentication"."subject" ADD CONSTRAINT "subject_id_system_account_fkey" FOREIGN KEY ("tenant_id","system_account_id") REFERENCES "authentication"."system_account"("tenant_id","id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
103
103
|
ALTER TABLE "authentication"."subject" ADD CONSTRAINT "subject_id_user_fkey" FOREIGN KEY ("tenant_id","user_id") REFERENCES "authentication"."user"("tenant_id","id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"id": "
|
|
2
|
+
"id": "685f89da-0f2a-4523-9cbc-c9daea5f70c2",
|
|
3
3
|
"prevId": "00000000-0000-0000-0000-000000000000",
|
|
4
4
|
"version": "7",
|
|
5
5
|
"dialect": "postgresql",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"primaryKey": false,
|
|
22
22
|
"notNull": true
|
|
23
23
|
},
|
|
24
|
-
"
|
|
25
|
-
"name": "
|
|
24
|
+
"subject_id": {
|
|
25
|
+
"name": "subject_id",
|
|
26
26
|
"type": "uuid",
|
|
27
27
|
"primaryKey": false,
|
|
28
28
|
"notNull": true
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"schemaTo": "authentication",
|
|
87
87
|
"columnsFrom": [
|
|
88
88
|
"tenant_id",
|
|
89
|
-
"
|
|
89
|
+
"subject_id"
|
|
90
90
|
],
|
|
91
91
|
"columnsTo": [
|
|
92
92
|
"tenant_id",
|
|
@@ -106,12 +106,12 @@
|
|
|
106
106
|
}
|
|
107
107
|
},
|
|
108
108
|
"uniqueConstraints": {
|
|
109
|
-
"
|
|
110
|
-
"name": "
|
|
109
|
+
"credentials_tenant_id_subject_id_unique": {
|
|
110
|
+
"name": "credentials_tenant_id_subject_id_unique",
|
|
111
111
|
"nullsNotDistinct": false,
|
|
112
112
|
"columns": [
|
|
113
113
|
"tenant_id",
|
|
114
|
-
"
|
|
114
|
+
"subject_id"
|
|
115
115
|
]
|
|
116
116
|
}
|
|
117
117
|
},
|
|
@@ -136,8 +136,8 @@
|
|
|
136
136
|
"primaryKey": false,
|
|
137
137
|
"notNull": true
|
|
138
138
|
},
|
|
139
|
-
"
|
|
140
|
-
"name": "
|
|
139
|
+
"subject_id": {
|
|
140
|
+
"name": "subject_id",
|
|
141
141
|
"type": "uuid",
|
|
142
142
|
"primaryKey": false,
|
|
143
143
|
"notNull": true
|
|
@@ -213,7 +213,7 @@
|
|
|
213
213
|
"schemaTo": "authentication",
|
|
214
214
|
"columnsFrom": [
|
|
215
215
|
"tenant_id",
|
|
216
|
-
"
|
|
216
|
+
"subject_id"
|
|
217
217
|
],
|
|
218
218
|
"columnsTo": [
|
|
219
219
|
"tenant_id",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tstdl/base",
|
|
3
|
-
"version": "0.93.
|
|
3
|
+
"version": "0.93.85",
|
|
4
4
|
"author": "Patrick Hein",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -48,6 +48,8 @@
|
|
|
48
48
|
"./authentication/server": "./authentication/server/index.js",
|
|
49
49
|
"./browser": "./browser/index.js",
|
|
50
50
|
"./cancellation": "./cancellation/index.js",
|
|
51
|
+
"./circuit-breaker": "./circuit-breaker/index.js",
|
|
52
|
+
"./circuit-breaker/postgres": "./circuit-breaker/postgres/index.js",
|
|
51
53
|
"./cookie": "./cookie/index.js",
|
|
52
54
|
"./css": "./css/index.js",
|
|
53
55
|
"./data-structures": "./data-structures/index.js",
|