@sixb/sqlite 0.1.12 → 0.1.14
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/auth-storage/access-tokens.d.ts +0 -1
- package/dist/auth-storage/access-tokens.d.ts.map +1 -1
- package/dist/auth-storage/auth-storage.d.ts +2 -1
- package/dist/auth-storage/auth-storage.d.ts.map +1 -1
- package/dist/auth-storage/device-authorizations.d.ts.map +1 -1
- package/dist/auth-storage/rows.d.ts +7 -4
- package/dist/auth-storage/rows.d.ts.map +1 -1
- package/dist/auth-storage/sessions.d.ts +8 -1
- package/dist/auth-storage/sessions.d.ts.map +1 -1
- package/dist/auth-storage/shared.d.ts.map +1 -1
- package/dist/file-upload-session-storage.d.ts +6 -0
- package/dist/file-upload-session-storage.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +441 -123
- package/dist/index.js.map +18 -17
- package/dist/migrations.d.ts.map +1 -1
- package/dist/objects/storage.d.ts.map +1 -1
- package/dist/ontology-storage/materializations.d.ts +0 -2
- package/dist/ontology-storage/materializations.d.ts.map +1 -1
- package/dist/ontology-storage/shared.d.ts +2 -1
- package/dist/ontology-storage/shared.d.ts.map +1 -1
- package/dist/workflow-intervention-storage.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/auth-storage/access-tokens.ts +11 -18
- package/src/auth-storage/auth-storage.ts +49 -86
- package/src/auth-storage/device-authorizations.ts +3 -5
- package/src/auth-storage/rows.ts +18 -8
- package/src/auth-storage/sessions.ts +89 -4
- package/src/auth-storage/shared.ts +9 -3
- package/src/file-upload-session-storage.ts +136 -0
- package/src/index.ts +5 -0
- package/src/migrations/046-workflow-intervention-principals.sql +15 -0
- package/src/migrations/047-ontology-commit-attribution.sql +67 -0
- package/src/migrations/048-file-upload-sessions.sql +35 -0
- package/src/migrations/049-native-sessions.sql +12 -0
- package/src/migrations/050-directory-group-memberships.sql +21 -0
- package/src/migrations.ts +16 -0
- package/src/objects/query-compiler.ts +59 -4
- package/src/objects/reader.ts +4 -0
- package/src/objects/storage.ts +1 -0
- package/src/ontology-storage/materializations.ts +16 -59
- package/src/ontology-storage/shared.ts +7 -3
- package/src/workflow-intervention-storage.ts +9 -9
package/dist/migrations.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAIrC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAGV,YAAY,EACZ,aAAa,EACb,oBAAoB,EACrB,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAIrC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAGV,YAAY,EACZ,aAAa,EACb,oBAAoB,EACrB,MAAM,oBAAoB,CAAA;AAwH3B,eAAO,MAAM,yBAAyB,sBAAsB,CAAA;AAC5D,eAAO,MAAM,mBAAmB,mBAAmB,CAAA;AAEnD,eAAO,MAAM,uBAAuB,wBAyFlC,CAAA;AAEF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAQ9E;AAED,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAC1C,OAAO,GAAE,oBAAyB,GACjC,aAAa,CAAC,QAAQ,CAAC,CAEzB;AAED,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAS3D;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,eAAe,EAAE,CAOzF;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAA;CAC5C,GAAG,eAAe,CAoBlB;AAED,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM1E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/objects/storage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,+BAA+B,EAC/B,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,aAAa,EACb,uBAAuB,EACvB,yBAAyB,EACzB,iBAAiB,EACjB,SAAS,EACT,aAAa,EACb,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,iBAAiB,CAAA;AAMxB,MAAM,WAAW,0BAA0B;IACzC,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,gEAAgE;IAChE,UAAU,CAAC,EAAE,qBAAqB,CAAA;CACnC;
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/objects/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,8 +19,6 @@ export declare class SqliteOntologyMaterializationStorage implements OntologyMat
|
|
|
19
19
|
private requireReplacement;
|
|
20
20
|
private assertCommitAbsent;
|
|
21
21
|
private assertSource;
|
|
22
|
-
private assertObject;
|
|
23
|
-
private assertLink;
|
|
24
22
|
private assertFinalization;
|
|
25
23
|
private assertFinalCardinality;
|
|
26
24
|
private activateSource;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"materializations.d.ts","sourceRoot":"","sources":["../../src/ontology-storage/materializations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"materializations.d.ts","sourceRoot":"","sources":["../../src/ontology-storage/materializations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AA2B1C,OAAO,KAAK,EACV,8BAA8B,EAC9B,0BAA0B,EAC1B,4BAA4B,EAC5B,8BAA8B,EAC9B,yBAAyB,EACzB,sBAAsB,EACtB,wBAAwB,EACxB,uBAAuB,EAEvB,8BAA8B,EAC9B,uCAAuC,EAEvC,0BAA0B,EAC1B,6BAA6B,EAC7B,+BAA+B,EAC/B,8BAA8B,EAC9B,iCAAiC,EAClC,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAGL,KAAK,gCAAgC,EACtC,MAAM,2BAA2B,CAAA;AAkBlC,qBAAa,oCAAqC,YAAW,8BAA8B;IAKvF,OAAO,CAAC,QAAQ,CAAC,EAAE;IAJrB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+B;IACxD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;gBAGjC,EAAE,EAAE,QAAQ,EAC7B,OAAO,EAAE,gCAAgC,GAAG,IAAI;IAMlD,mBAAmB,CAAC,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAY1F,KAAK,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAkCvE,WAAW,CAChB,KAAK,EAAE,+BAA+B,GACrC,aAAa,CAAC,wBAAwB,CAAC;IAmDnC,4BAA4B,CACjC,KAAK,EAAE,iCAAiC,GACvC,aAAa,CAAC,0BAA0B,CAAC;IA6FtC,SAAS,CAAC,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpE,UAAU,CAAC,KAAK,EAAE,8BAA8B,GAAG,aAAa,CAAC,uBAAuB,CAAC;IAKnF,mBAAmB,CACvB,KAAK,EAAE,uCAAuC,GAC7C,OAAO,CAAC,SAAS,8BAA8B,EAAE,CAAC;IAK/C,UAAU,CAAC,KAAK,EAAE,8BAA8B,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBhE,QAAQ,CAAC,KAAK,EAAE,4BAA4B,GAAG,OAAO,CAAC,0BAA0B,CAAC;IAYxF,kBAAkB,IAAI,IAAI;IAI1B,OAAO,CAAC,kBAAkB;IA4D1B,OAAO,CAAC,kBAAkB;IA+C1B,OAAO,CAAC,YAAY;YAgBN,kBAAkB;IAwDhC,OAAO,CAAC,sBAAsB;IAwD9B,OAAO,CAAC,cAAc;IAsGtB,OAAO,CAAC,YAAY;IAsDpB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,SAAS;CAYlB"}
|
|
@@ -13,7 +13,8 @@ export interface SqliteOntologyCommitRow {
|
|
|
13
13
|
readonly origin_run_id: string | null;
|
|
14
14
|
readonly origin_batch_ordinal: number | null;
|
|
15
15
|
readonly origin: string;
|
|
16
|
-
readonly
|
|
16
|
+
readonly requested_by: string | null;
|
|
17
|
+
readonly executor: string;
|
|
17
18
|
readonly ontology_revision: string;
|
|
18
19
|
readonly projection_revision: string | null;
|
|
19
20
|
readonly ownership_hash: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/ontology-storage/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAG1C,OAAO,EAAE,4BAA4B,EAAE,MAAM,qCAAqC,CAAA;AAClF,OAAO,KAAK,EACV,yCAAyC,EACzC,oBAAoB,EAEpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,oBAAoB,CAAA;AAG3B,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,qBAAqB,EACrB,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,eAAe,GAChB,MAAM,+CAA+C,CAAA;AAEtD,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;AAE9E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IACrC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/ontology-storage/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-intervention-storage.d.ts","sourceRoot":"","sources":["../src/workflow-intervention-storage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,+BAA+B,EAC/B,+BAA+B,EAC/B,+BAA+B,EAC/B,8BAA8B,EAC9B,+BAA+B,
|
|
1
|
+
{"version":3,"file":"workflow-intervention-storage.d.ts","sourceRoot":"","sources":["../src/workflow-intervention-storage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,+BAA+B,EAC/B,+BAA+B,EAC/B,+BAA+B,EAC/B,8BAA8B,EAC9B,+BAA+B,EAE/B,+BAA+B,EAC/B,0BAA0B,EAC1B,2BAA2B,EAC5B,MAAM,oBAAoB,CAAA;AAI3B,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAA;AAEvB,MAAM,WAAW,wCAAwC;IACvD,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,gEAAgE;IAChE,UAAU,CAAC,EAAE,qBAAqB,CAAA;CACnC;AAED,qBAAa,iCAAkC,YAAW,2BAA2B;IACnF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuB;IAClD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAU;gBAEjB,OAAO,GAAE,wCAA6C;IAS5D,MAAM,CAAC,KAAK,EAAE,+BAA+B,GAAG,OAAO,CAAC,0BAA0B,CAAC;IAsDnF,MAAM,CAAC,KAAK,EAAE,+BAA+B,GAAG,OAAO,CAAC,0BAA0B,CAAC;IA6BnF,MAAM,CAAC,KAAK,EAAE,+BAA+B,GAAG,OAAO,CAAC,0BAA0B,CAAC;IA2BnF,MAAM,CAAC,KAAK,EAAE,+BAA+B,GAAG,OAAO,CAAC,0BAA0B,CAAC;IAyBnF,OAAO,CAAC,MAAM,EAAE;QACpB,SAAS,EAAE,MAAM,CAAA;QACjB,EAAE,EAAE,MAAM,CAAA;KACX,GAAG,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC;IAQxC,IAAI,CAAC,KAAK,EAAE,8BAA8B,GAAG,OAAO,CAAC,+BAA+B,CAAC;IA6F3F,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,0BAA0B;IAuBlC,OAAO,CAAC,mBAAmB;CAa5B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sixb/sqlite",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"description": "SQLite storage provider for Sixb",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sixb",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"prepack": "bun run build"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@sixb/core": "0.1.
|
|
40
|
+
"@sixb/core": "0.1.14"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@sixb/core": "0.1.
|
|
43
|
+
"@sixb/core": "0.1.14",
|
|
44
44
|
"@types/bun": "latest",
|
|
45
45
|
"typescript": "^5.7.0"
|
|
46
46
|
},
|
|
@@ -22,17 +22,14 @@ import {
|
|
|
22
22
|
toIso,
|
|
23
23
|
} from "./shared"
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
db: Database,
|
|
27
|
-
input: CreateAuthAccessTokenInput
|
|
28
|
-
): AccessTokenRecord {
|
|
25
|
+
function createAuthAccessToken(db: Database, input: CreateAuthAccessTokenInput): AccessTokenRecord {
|
|
29
26
|
const id = assertNonEmpty(input.id, "Access token id")
|
|
30
27
|
const projectId = assertNonEmpty(input.projectId, "Project id")
|
|
31
28
|
const name = assertNonEmpty(input.name, "Access token name")
|
|
32
|
-
const subjectId = assertNonEmpty(input.
|
|
29
|
+
const subjectId = assertNonEmpty(input.subject.id, "Access token subject id")
|
|
33
30
|
const tokenHash = assertNonEmpty(input.tokenHash, "Access token hash")
|
|
34
31
|
assertKindMatchesSubject(input)
|
|
35
|
-
assertSubjectExists(db, projectId, input.
|
|
32
|
+
assertSubjectExists(db, projectId, input.subject.type, subjectId)
|
|
36
33
|
const groupIds = input.groupIds === undefined ? undefined : normalizeGroupIds(input.groupIds)
|
|
37
34
|
|
|
38
35
|
try {
|
|
@@ -59,7 +56,7 @@ export function createAuthAccessToken(
|
|
|
59
56
|
id,
|
|
60
57
|
name,
|
|
61
58
|
input.kind,
|
|
62
|
-
input.
|
|
59
|
+
input.subject.type,
|
|
63
60
|
subjectId,
|
|
64
61
|
tokenHash,
|
|
65
62
|
serializeOptionalStringArray(groupIds),
|
|
@@ -114,13 +111,9 @@ export class SqliteAuthAccessTokenStore implements AuthAccessTokenStore {
|
|
|
114
111
|
whereClauses.push("kind = ?")
|
|
115
112
|
args.push(input.kind)
|
|
116
113
|
}
|
|
117
|
-
if (input.
|
|
118
|
-
whereClauses.push("subject_type = ?")
|
|
119
|
-
args.push(input.
|
|
120
|
-
}
|
|
121
|
-
if (input.subjectId) {
|
|
122
|
-
whereClauses.push("subject_id = ?")
|
|
123
|
-
args.push(input.subjectId)
|
|
114
|
+
if (input.subject) {
|
|
115
|
+
whereClauses.push("subject_type = ?", "subject_id = ?")
|
|
116
|
+
args.push(input.subject.type, input.subject.id)
|
|
124
117
|
}
|
|
125
118
|
if (!input.includeRevoked) {
|
|
126
119
|
whereClauses.push("revoked_at IS NULL")
|
|
@@ -259,7 +252,7 @@ export class SqliteAuthAccessTokenStore implements AuthAccessTokenStore {
|
|
|
259
252
|
function assertSubjectExists(
|
|
260
253
|
db: Database,
|
|
261
254
|
projectId: string,
|
|
262
|
-
subjectType: CreateAuthAccessTokenInput["
|
|
255
|
+
subjectType: CreateAuthAccessTokenInput["subject"]["type"],
|
|
263
256
|
subjectId: string
|
|
264
257
|
): void {
|
|
265
258
|
if (subjectType === "user") {
|
|
@@ -285,14 +278,14 @@ function assertSubjectExists(
|
|
|
285
278
|
|
|
286
279
|
function assertKindMatchesSubject(input: CreateAuthAccessTokenInput): void {
|
|
287
280
|
if (
|
|
288
|
-
(input.kind === "personal" && input.
|
|
289
|
-
(input.kind === "serviceAccount" && input.
|
|
281
|
+
(input.kind === "personal" && input.subject.type === "user") ||
|
|
282
|
+
(input.kind === "serviceAccount" && input.subject.type === "serviceAccount")
|
|
290
283
|
) {
|
|
291
284
|
return
|
|
292
285
|
}
|
|
293
286
|
|
|
294
287
|
throw new AuthStorageError(
|
|
295
288
|
"invalid_input",
|
|
296
|
-
`[Sixb] Access token kind '${input.kind}' cannot target subject type '${input.
|
|
289
|
+
`[Sixb] Access token kind '${input.kind}' cannot target subject type '${input.subject.type}'.`
|
|
297
290
|
)
|
|
298
291
|
}
|
|
@@ -8,6 +8,7 @@ import type {
|
|
|
8
8
|
CompleteSignInResult,
|
|
9
9
|
DeviceAuthorizationRecord,
|
|
10
10
|
GroupMembershipRecord,
|
|
11
|
+
GroupMembershipSource,
|
|
11
12
|
InvitationRecord,
|
|
12
13
|
SessionRecord,
|
|
13
14
|
SuspendUserAndRevokeSessionsInput,
|
|
@@ -22,7 +23,7 @@ import {
|
|
|
22
23
|
runImmediateTransaction,
|
|
23
24
|
type SqliteStoreConnection,
|
|
24
25
|
} from "../transactions"
|
|
25
|
-
import {
|
|
26
|
+
import { SqliteAuthAccessTokenStore } from "./access-tokens"
|
|
26
27
|
import {
|
|
27
28
|
getDeviceAuthorizationById,
|
|
28
29
|
SqliteAuthDeviceAuthorizationStore,
|
|
@@ -118,7 +119,7 @@ export class SqliteAuthStorage implements AuthStorage {
|
|
|
118
119
|
)
|
|
119
120
|
}
|
|
120
121
|
assertCompletableDeviceAuthorization(authorization, input)
|
|
121
|
-
const
|
|
122
|
+
const session = createSession(this.db, input.session)
|
|
122
123
|
this.db
|
|
123
124
|
.query(`
|
|
124
125
|
UPDATE auth_device_authorizations
|
|
@@ -132,7 +133,7 @@ export class SqliteAuthStorage implements AuthStorage {
|
|
|
132
133
|
status: "consumed",
|
|
133
134
|
consumedAt: new Date(input.completedAt),
|
|
134
135
|
},
|
|
135
|
-
|
|
136
|
+
session,
|
|
136
137
|
}
|
|
137
138
|
})
|
|
138
139
|
}
|
|
@@ -200,27 +201,6 @@ export class SqliteAuthStorage implements AuthStorage {
|
|
|
200
201
|
}
|
|
201
202
|
}
|
|
202
203
|
|
|
203
|
-
if (
|
|
204
|
-
shouldCreateUser &&
|
|
205
|
-
!activeInvitation &&
|
|
206
|
-
input.allowUserCreationWithoutInvitation &&
|
|
207
|
-
input.requireNoActiveUsersForUserCreation &&
|
|
208
|
-
hasActiveUsers(this.db, projectId)
|
|
209
|
-
) {
|
|
210
|
-
consumeMagicLink(this.db, {
|
|
211
|
-
projectId,
|
|
212
|
-
id: input.magicLinkId,
|
|
213
|
-
tokenHash: input.tokenHash,
|
|
214
|
-
consumedAt: completedAt,
|
|
215
|
-
})
|
|
216
|
-
return {
|
|
217
|
-
error: new AuthStorageError(
|
|
218
|
-
"user_creation_not_allowed",
|
|
219
|
-
`[Sixb] Magic link '${input.magicLinkId}' cannot create a user for project '${projectId}'.`
|
|
220
|
-
),
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
204
|
validateCompleteSessionInput(this.db, projectId, input.session)
|
|
225
205
|
assertSignInSessionAudience(projectId, input.session.audience, magicLink.audience)
|
|
226
206
|
|
|
@@ -259,8 +239,9 @@ export class SqliteAuthStorage implements AuthStorage {
|
|
|
259
239
|
projectId,
|
|
260
240
|
user,
|
|
261
241
|
})
|
|
262
|
-
const groupMemberships = this.
|
|
242
|
+
const groupMemberships = this.applyGroups({
|
|
263
243
|
completedAt,
|
|
244
|
+
source: "manual",
|
|
264
245
|
existing: invitation.groupMemberships,
|
|
265
246
|
groupIds: manualGroupIds,
|
|
266
247
|
projectId,
|
|
@@ -338,16 +319,6 @@ export class SqliteAuthStorage implements AuthStorage {
|
|
|
338
319
|
}
|
|
339
320
|
}
|
|
340
321
|
|
|
341
|
-
if (!identity && userRow && (!input.autoLinkByVerifiedEmail || !input.emailVerified)) {
|
|
342
|
-
this.consumeOidcAttempt(input, completedAt, projectId)
|
|
343
|
-
return {
|
|
344
|
-
error: new AuthStorageError(
|
|
345
|
-
"email_link_not_allowed",
|
|
346
|
-
`[Sixb] OIDC identity cannot auto-link to user '${userRow.id}' for project '${projectId}'.`
|
|
347
|
-
),
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
322
|
if (userRow?.status === "suspended") {
|
|
352
323
|
this.consumeOidcAttempt(input, completedAt, projectId)
|
|
353
324
|
return {
|
|
@@ -358,16 +329,6 @@ export class SqliteAuthStorage implements AuthStorage {
|
|
|
358
329
|
}
|
|
359
330
|
}
|
|
360
331
|
|
|
361
|
-
if (shouldCreateUser && !input.emailVerified) {
|
|
362
|
-
this.consumeOidcAttempt(input, completedAt, projectId)
|
|
363
|
-
return {
|
|
364
|
-
error: new AuthStorageError(
|
|
365
|
-
"user_creation_not_allowed",
|
|
366
|
-
`[Sixb] OIDC authorization attempt '${input.oidcAuthorizationAttemptId}' cannot create a user for project '${projectId}'.`
|
|
367
|
-
),
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
|
|
371
332
|
if (shouldCreateUser && !activeInvitation && !input.allowUserCreationWithoutInvitation) {
|
|
372
333
|
this.consumeOidcAttempt(input, completedAt, projectId)
|
|
373
334
|
return {
|
|
@@ -378,22 +339,6 @@ export class SqliteAuthStorage implements AuthStorage {
|
|
|
378
339
|
}
|
|
379
340
|
}
|
|
380
341
|
|
|
381
|
-
if (
|
|
382
|
-
shouldCreateUser &&
|
|
383
|
-
!activeInvitation &&
|
|
384
|
-
input.allowUserCreationWithoutInvitation &&
|
|
385
|
-
input.requireNoActiveUsersForUserCreation &&
|
|
386
|
-
hasActiveUsers(this.db, projectId)
|
|
387
|
-
) {
|
|
388
|
-
this.consumeOidcAttempt(input, completedAt, projectId)
|
|
389
|
-
return {
|
|
390
|
-
error: new AuthStorageError(
|
|
391
|
-
"user_creation_not_allowed",
|
|
392
|
-
`[Sixb] OIDC authorization attempt '${input.oidcAuthorizationAttemptId}' cannot create a user for project '${projectId}'.`
|
|
393
|
-
),
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
342
|
validateCompleteSessionInput(this.db, projectId, input.session)
|
|
398
343
|
assertSignInSessionAudience(projectId, input.session.audience, attempt.audience)
|
|
399
344
|
|
|
@@ -438,10 +383,17 @@ export class SqliteAuthStorage implements AuthStorage {
|
|
|
438
383
|
projectId,
|
|
439
384
|
user,
|
|
440
385
|
})
|
|
441
|
-
const groupMemberships = this.
|
|
386
|
+
const groupMemberships = this.syncDirectoryGroups({
|
|
442
387
|
completedAt,
|
|
443
|
-
existing:
|
|
444
|
-
|
|
388
|
+
existing: this.applyGroups({
|
|
389
|
+
completedAt,
|
|
390
|
+
source: "manual",
|
|
391
|
+
existing: invitation.groupMemberships,
|
|
392
|
+
groupIds: manualGroupIds,
|
|
393
|
+
projectId,
|
|
394
|
+
userId: user.id,
|
|
395
|
+
}),
|
|
396
|
+
groupIds: input.directoryGroupIds,
|
|
445
397
|
projectId,
|
|
446
398
|
userId: user.id,
|
|
447
399
|
})
|
|
@@ -684,11 +636,12 @@ export class SqliteAuthStorage implements AuthStorage {
|
|
|
684
636
|
return { invitation, groupMemberships }
|
|
685
637
|
}
|
|
686
638
|
|
|
687
|
-
private
|
|
639
|
+
private applyGroups(input: {
|
|
688
640
|
readonly completedAt: Date
|
|
689
641
|
readonly existing: readonly GroupMembershipRecord[]
|
|
690
642
|
readonly groupIds: readonly string[]
|
|
691
643
|
readonly projectId: string
|
|
644
|
+
readonly source: GroupMembershipSource
|
|
692
645
|
readonly userId: string
|
|
693
646
|
}): readonly GroupMembershipRecord[] {
|
|
694
647
|
const groupMemberships = [...input.existing]
|
|
@@ -699,7 +652,7 @@ export class SqliteAuthStorage implements AuthStorage {
|
|
|
699
652
|
projectId: input.projectId,
|
|
700
653
|
userId: input.userId,
|
|
701
654
|
groupId,
|
|
702
|
-
source:
|
|
655
|
+
source: input.source,
|
|
703
656
|
createdAt: input.completedAt,
|
|
704
657
|
})
|
|
705
658
|
)
|
|
@@ -707,6 +660,34 @@ export class SqliteAuthStorage implements AuthStorage {
|
|
|
707
660
|
|
|
708
661
|
return groupMemberships
|
|
709
662
|
}
|
|
663
|
+
// Directory memberships become exactly `groupIds`. A group the user already holds from another
|
|
664
|
+
// source keeps that source, and memberships from other sources are never removed.
|
|
665
|
+
private syncDirectoryGroups(input: {
|
|
666
|
+
readonly completedAt: Date
|
|
667
|
+
readonly existing: readonly GroupMembershipRecord[]
|
|
668
|
+
readonly groupIds?: readonly string[]
|
|
669
|
+
readonly projectId: string
|
|
670
|
+
readonly userId: string
|
|
671
|
+
}): readonly GroupMembershipRecord[] {
|
|
672
|
+
if (!input.groupIds) {
|
|
673
|
+
return input.existing
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
const groupIds = normalizeGroupIds(input.groupIds)
|
|
677
|
+
this.db
|
|
678
|
+
.query(
|
|
679
|
+
`
|
|
680
|
+
DELETE FROM auth_group_memberships
|
|
681
|
+
WHERE project_id = ?
|
|
682
|
+
AND user_id = ?
|
|
683
|
+
AND source = 'directory'
|
|
684
|
+
AND group_id NOT IN (${groupIds.map(() => "?").join(", ")})
|
|
685
|
+
`
|
|
686
|
+
)
|
|
687
|
+
.run(input.projectId, input.userId, ...groupIds)
|
|
688
|
+
|
|
689
|
+
return this.applyGroups({ ...input, groupIds, source: "directory" })
|
|
690
|
+
}
|
|
710
691
|
|
|
711
692
|
private createSignInSession(input: {
|
|
712
693
|
readonly projectId: string
|
|
@@ -792,22 +773,6 @@ export class SqliteAuthStorage implements AuthStorage {
|
|
|
792
773
|
}
|
|
793
774
|
}
|
|
794
775
|
|
|
795
|
-
function hasActiveUsers(db: Database, projectId: string): boolean {
|
|
796
|
-
const row = db
|
|
797
|
-
.query(
|
|
798
|
-
`
|
|
799
|
-
SELECT 1 AS active
|
|
800
|
-
FROM auth_users
|
|
801
|
-
WHERE project_id = ?
|
|
802
|
-
AND status = 'active'
|
|
803
|
-
LIMIT 1
|
|
804
|
-
`
|
|
805
|
-
)
|
|
806
|
-
.get(projectId) as { readonly active: number } | null
|
|
807
|
-
|
|
808
|
-
return row !== null
|
|
809
|
-
}
|
|
810
|
-
|
|
811
776
|
function assertSignInSessionAudience(
|
|
812
777
|
projectId: string,
|
|
813
778
|
sessionAudience: string,
|
|
@@ -850,10 +815,8 @@ function assertCompletableDeviceAuthorization(
|
|
|
850
815
|
authorization.expiresAt <= input.completedAt ||
|
|
851
816
|
!authorization.approvedUserId ||
|
|
852
817
|
!authorization.approvedSessionId ||
|
|
853
|
-
input.
|
|
854
|
-
input.
|
|
855
|
-
input.accessToken.subjectId !== authorization.approvedUserId ||
|
|
856
|
-
input.accessToken.createdBySessionId !== authorization.approvedSessionId
|
|
818
|
+
input.session.projectId !== input.projectId ||
|
|
819
|
+
input.session.userId !== authorization.approvedUserId
|
|
857
820
|
) {
|
|
858
821
|
throw new AuthStorageError(
|
|
859
822
|
"invalid_device_authorization",
|
|
@@ -33,9 +33,9 @@ export class SqliteAuthDeviceAuthorizationStore implements AuthDeviceAuthorizati
|
|
|
33
33
|
this.db
|
|
34
34
|
.query(`
|
|
35
35
|
INSERT INTO auth_device_authorizations (
|
|
36
|
-
project_id, id, device_code_hash, user_code, client_name,
|
|
37
|
-
|
|
38
|
-
) VALUES (?, ?, ?, ?, ?,
|
|
36
|
+
project_id, id, device_code_hash, user_code, client_name, status, created_at,
|
|
37
|
+
expires_at
|
|
38
|
+
) VALUES (?, ?, ?, ?, ?, 'pending', ?, ?)
|
|
39
39
|
`)
|
|
40
40
|
.run(
|
|
41
41
|
assertNonEmpty(input.projectId, "Project id"),
|
|
@@ -43,8 +43,6 @@ export class SqliteAuthDeviceAuthorizationStore implements AuthDeviceAuthorizati
|
|
|
43
43
|
assertNonEmpty(input.deviceCodeHash, "Device code hash"),
|
|
44
44
|
assertNonEmpty(input.userCode, "User code"),
|
|
45
45
|
assertNonEmpty(input.clientName, "Client name"),
|
|
46
|
-
assertNonEmpty(input.tokenName, "Token name"),
|
|
47
|
-
toIso(input.tokenExpiresAt),
|
|
48
46
|
toIso(input.createdAt),
|
|
49
47
|
toIso(input.expiresAt)
|
|
50
48
|
)
|
package/src/auth-storage/rows.ts
CHANGED
|
@@ -55,7 +55,7 @@ export interface SqliteAuthServiceAccountGroupMembershipRow {
|
|
|
55
55
|
readonly project_id: string
|
|
56
56
|
readonly service_account_id: string
|
|
57
57
|
readonly group_id: string
|
|
58
|
-
readonly source:
|
|
58
|
+
readonly source: ServiceAccountGroupMembershipRecord["source"]
|
|
59
59
|
readonly created_at: string
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -73,6 +73,11 @@ export interface SqliteAuthSessionRow {
|
|
|
73
73
|
readonly last_seen_at: string | null
|
|
74
74
|
readonly user_agent: string | null
|
|
75
75
|
readonly ip_address: string | null
|
|
76
|
+
readonly client_name: string | null
|
|
77
|
+
readonly access_expires_at: string | null
|
|
78
|
+
readonly refresh_token_hash: string | null
|
|
79
|
+
readonly previous_refresh_token_hash: string | null
|
|
80
|
+
readonly refreshed_at: string | null
|
|
76
81
|
}
|
|
77
82
|
|
|
78
83
|
export interface SqliteAuthAccessTokenRow {
|
|
@@ -80,7 +85,7 @@ export interface SqliteAuthAccessTokenRow {
|
|
|
80
85
|
readonly id: string
|
|
81
86
|
readonly name: string
|
|
82
87
|
readonly kind: AccessTokenRecord["kind"]
|
|
83
|
-
readonly subject_type: AccessTokenRecord["
|
|
88
|
+
readonly subject_type: AccessTokenRecord["subject"]["type"]
|
|
84
89
|
readonly subject_id: string
|
|
85
90
|
readonly token_hash: string
|
|
86
91
|
readonly group_ids: string | null
|
|
@@ -152,8 +157,6 @@ export interface SqliteAuthDeviceAuthorizationRow {
|
|
|
152
157
|
readonly device_code_hash: string
|
|
153
158
|
readonly user_code: string
|
|
154
159
|
readonly client_name: string
|
|
155
|
-
readonly token_name: string
|
|
156
|
-
readonly token_expires_at: string
|
|
157
160
|
readonly status: DeviceAuthorizationRecord["status"]
|
|
158
161
|
readonly approved_user_id: string | null
|
|
159
162
|
readonly approved_session_id: string | null
|
|
@@ -236,6 +239,16 @@ export function rowToSessionRecord(row: SqliteAuthSessionRow): SessionRecord {
|
|
|
236
239
|
lastSeenAt: row.last_seen_at ? new Date(row.last_seen_at) : undefined,
|
|
237
240
|
userAgent: row.user_agent ?? undefined,
|
|
238
241
|
ipAddress: row.ip_address ?? undefined,
|
|
242
|
+
bearer:
|
|
243
|
+
row.refresh_token_hash !== null && row.client_name !== null && row.access_expires_at !== null
|
|
244
|
+
? {
|
|
245
|
+
clientName: row.client_name,
|
|
246
|
+
accessExpiresAt: new Date(row.access_expires_at),
|
|
247
|
+
refreshTokenHash: row.refresh_token_hash,
|
|
248
|
+
previousRefreshTokenHash: row.previous_refresh_token_hash ?? undefined,
|
|
249
|
+
refreshedAt: row.refreshed_at ? new Date(row.refreshed_at) : undefined,
|
|
250
|
+
}
|
|
251
|
+
: undefined,
|
|
239
252
|
}
|
|
240
253
|
}
|
|
241
254
|
|
|
@@ -245,8 +258,7 @@ export function rowToAccessTokenRecord(row: SqliteAuthAccessTokenRow): AccessTok
|
|
|
245
258
|
projectId: row.project_id,
|
|
246
259
|
name: row.name,
|
|
247
260
|
kind: row.kind,
|
|
248
|
-
|
|
249
|
-
subjectId: row.subject_id,
|
|
261
|
+
subject: { type: row.subject_type, id: row.subject_id },
|
|
250
262
|
tokenHash: row.token_hash,
|
|
251
263
|
groupIds: parseOptionalStringArray(row.group_ids),
|
|
252
264
|
createdByPrincipal:
|
|
@@ -347,8 +359,6 @@ export function rowToDeviceAuthorizationRecord(
|
|
|
347
359
|
deviceCodeHash: row.device_code_hash,
|
|
348
360
|
userCode: row.user_code,
|
|
349
361
|
clientName: row.client_name,
|
|
350
|
-
tokenName: row.token_name,
|
|
351
|
-
tokenExpiresAt: new Date(row.token_expires_at),
|
|
352
362
|
status: row.status,
|
|
353
363
|
approvedUserId: row.approved_user_id ?? undefined,
|
|
354
364
|
approvedSessionId: row.approved_session_id ?? undefined,
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { Database } from "bun:sqlite"
|
|
2
2
|
import type { AuthSessionAudience } from "@sixb/core"
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
AuthSessionStore,
|
|
5
|
+
CreateAuthSessionInput,
|
|
6
|
+
RotateSessionRefreshTokenResult,
|
|
7
|
+
SessionRecord,
|
|
8
|
+
} from "@sixb/core/storage"
|
|
4
9
|
import { AuthStorageError } from "@sixb/core/storage"
|
|
5
10
|
import { runImmediateTransaction } from "../transactions"
|
|
6
11
|
import type { SqliteAuthSessionRow } from "./rows"
|
|
@@ -99,11 +104,10 @@ export class SqliteAuthSessionStore implements AuthSessionStore {
|
|
|
99
104
|
|
|
100
105
|
if (
|
|
101
106
|
!row ||
|
|
107
|
+
row.refresh_token_hash !== null ||
|
|
102
108
|
row.audience !== params.audience ||
|
|
103
109
|
row.token_hash !== params.tokenHash ||
|
|
104
|
-
row.
|
|
105
|
-
new Date(row.expires_at) <= params.now ||
|
|
106
|
-
(row.absolute_expires_at !== null && new Date(row.absolute_expires_at) <= params.now)
|
|
110
|
+
!isLiveSessionRow(row, params.now)
|
|
107
111
|
) {
|
|
108
112
|
return null
|
|
109
113
|
}
|
|
@@ -111,6 +115,78 @@ export class SqliteAuthSessionStore implements AuthSessionStore {
|
|
|
111
115
|
return rowToSessionRecord(row)
|
|
112
116
|
}
|
|
113
117
|
|
|
118
|
+
async findValidByAccessTokenHash(params: {
|
|
119
|
+
readonly projectId: string
|
|
120
|
+
readonly id: string
|
|
121
|
+
readonly tokenHash: string
|
|
122
|
+
readonly now: Date
|
|
123
|
+
}): Promise<SessionRecord | null> {
|
|
124
|
+
const row = getSessionRowById(this.db, params)
|
|
125
|
+
if (
|
|
126
|
+
!row ||
|
|
127
|
+
row.access_expires_at === null ||
|
|
128
|
+
row.token_hash !== params.tokenHash ||
|
|
129
|
+
new Date(row.access_expires_at) <= params.now ||
|
|
130
|
+
!isLiveSessionRow(row, params.now)
|
|
131
|
+
) {
|
|
132
|
+
return null
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return rowToSessionRecord(row)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async rotateRefreshToken(
|
|
139
|
+
params: Parameters<AuthSessionStore["rotateRefreshToken"]>[0]
|
|
140
|
+
): Promise<RotateSessionRefreshTokenResult> {
|
|
141
|
+
return runImmediateTransaction(this.db, (): RotateSessionRefreshTokenResult => {
|
|
142
|
+
const row = getSessionRowById(this.db, params)
|
|
143
|
+
if (!row?.refresh_token_hash || !isLiveSessionRow(row, params.now)) {
|
|
144
|
+
return { status: "invalid" }
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const replacedRecently =
|
|
148
|
+
row.previous_refresh_token_hash === params.refreshTokenHash &&
|
|
149
|
+
row.refreshed_at !== null &&
|
|
150
|
+
params.now.getTime() - new Date(row.refreshed_at).getTime() <= params.reuseGraceMs
|
|
151
|
+
if (row.refresh_token_hash !== params.refreshTokenHash && !replacedRecently) {
|
|
152
|
+
if (row.previous_refresh_token_hash !== params.refreshTokenHash) {
|
|
153
|
+
return { status: "invalid" }
|
|
154
|
+
}
|
|
155
|
+
this.db
|
|
156
|
+
.query("UPDATE auth_sessions SET revoked_at = ? WHERE project_id = ? AND id = ?")
|
|
157
|
+
.run(toIso(params.now), params.projectId, params.id)
|
|
158
|
+
return { status: "reused" }
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const expiresAt = toIso(params.next.expiresAt)
|
|
162
|
+
this.db
|
|
163
|
+
.query(`
|
|
164
|
+
UPDATE auth_sessions
|
|
165
|
+
SET token_hash = ?,
|
|
166
|
+
access_expires_at = ?,
|
|
167
|
+
previous_refresh_token_hash = refresh_token_hash,
|
|
168
|
+
refresh_token_hash = ?,
|
|
169
|
+
refreshed_at = ?,
|
|
170
|
+
last_seen_at = ?,
|
|
171
|
+
expires_at = MAX(expires_at, MIN(?, COALESCE(absolute_expires_at, ?)))
|
|
172
|
+
WHERE project_id = ? AND id = ?
|
|
173
|
+
`)
|
|
174
|
+
.run(
|
|
175
|
+
params.next.tokenHash,
|
|
176
|
+
toIso(params.next.accessExpiresAt),
|
|
177
|
+
params.next.refreshTokenHash,
|
|
178
|
+
toIso(params.now),
|
|
179
|
+
toIso(params.now),
|
|
180
|
+
expiresAt,
|
|
181
|
+
expiresAt,
|
|
182
|
+
params.projectId,
|
|
183
|
+
params.id
|
|
184
|
+
)
|
|
185
|
+
const session = getSessionById(this.db, params)
|
|
186
|
+
return session ? { status: "rotated", session } : { status: "invalid" }
|
|
187
|
+
})
|
|
188
|
+
}
|
|
189
|
+
|
|
114
190
|
async renewIfValid(params: {
|
|
115
191
|
readonly projectId: string
|
|
116
192
|
readonly id: string
|
|
@@ -135,6 +211,7 @@ export class SqliteAuthSessionStore implements AuthSessionStore {
|
|
|
135
211
|
AND id = ?
|
|
136
212
|
AND audience = ?
|
|
137
213
|
AND token_hash = ?
|
|
214
|
+
AND refresh_token_hash IS NULL
|
|
138
215
|
AND revoked_at IS NULL
|
|
139
216
|
AND expires_at > ?
|
|
140
217
|
AND (absolute_expires_at IS NULL OR absolute_expires_at > ?)
|
|
@@ -228,3 +305,11 @@ export class SqliteAuthSessionStore implements AuthSessionStore {
|
|
|
228
305
|
})
|
|
229
306
|
}
|
|
230
307
|
}
|
|
308
|
+
|
|
309
|
+
function isLiveSessionRow(row: SqliteAuthSessionRow, now: Date): boolean {
|
|
310
|
+
return (
|
|
311
|
+
row.revoked_at === null &&
|
|
312
|
+
new Date(row.expires_at) > now &&
|
|
313
|
+
(row.absolute_expires_at === null || new Date(row.absolute_expires_at) > now)
|
|
314
|
+
)
|
|
315
|
+
}
|
|
@@ -425,8 +425,11 @@ export function createSession(
|
|
|
425
425
|
expires_at,
|
|
426
426
|
absolute_expires_at,
|
|
427
427
|
user_agent,
|
|
428
|
-
ip_address
|
|
429
|
-
|
|
428
|
+
ip_address,
|
|
429
|
+
client_name,
|
|
430
|
+
access_expires_at,
|
|
431
|
+
refresh_token_hash
|
|
432
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
430
433
|
`
|
|
431
434
|
).run(
|
|
432
435
|
projectId,
|
|
@@ -439,7 +442,10 @@ export function createSession(
|
|
|
439
442
|
toIso(input.expiresAt),
|
|
440
443
|
input.absoluteExpiresAt ? toIso(input.absoluteExpiresAt) : null,
|
|
441
444
|
input.userAgent ?? null,
|
|
442
|
-
input.ipAddress ?? null
|
|
445
|
+
input.ipAddress ?? null,
|
|
446
|
+
input.bearer ? assertNonEmpty(input.bearer.clientName, "Session client name") : null,
|
|
447
|
+
input.bearer ? toIso(input.bearer.accessExpiresAt) : null,
|
|
448
|
+
input.bearer ? assertNonEmpty(input.bearer.refreshTokenHash, "Refresh token hash") : null
|
|
443
449
|
)
|
|
444
450
|
|
|
445
451
|
const session = getSessionById(db, { projectId, id })
|