@sixb/pg 0.1.19 → 0.1.20
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/auth-storage.d.ts.map +1 -1
- package/dist/auth-storage/magic-links.d.ts.map +1 -1
- package/dist/auth-storage/oidc-attempts.d.ts.map +1 -1
- package/dist/auth-storage/rows.d.ts +0 -3
- package/dist/auth-storage/rows.d.ts.map +1 -1
- package/dist/auth-storage/sessions.d.ts +0 -10
- package/dist/auth-storage/sessions.d.ts.map +1 -1
- package/dist/auth-storage/shared.d.ts +1 -2
- package/dist/auth-storage/shared.d.ts.map +1 -1
- package/dist/index.js +30 -78
- package/dist/index.js.map +9 -9
- package/dist/migrations.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/auth-storage/auth-storage.ts +1 -22
- package/src/auth-storage/magic-links.ts +0 -4
- package/src/auth-storage/oidc-attempts.ts +0 -4
- package/src/auth-storage/rows.ts +0 -6
- package/src/auth-storage/sessions.ts +1 -33
- package/src/auth-storage/shared.ts +3 -35
- package/src/migrations/062-drop-auth-audience.sql +19 -0
- package/src/migrations.ts +2 -0
package/dist/migrations.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAGV,YAAY,EACZ,aAAa,EACb,oBAAoB,EACrB,MAAM,oBAAoB,CAAA;AAqH3B,OAAO,KAAK,EAAe,GAAG,EAAa,MAAM,aAAa,CAAA;AAG9D,MAAM,WAAW,wBAAwB;IACvC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACrC;AAED,eAAO,MAAM,2BAA2B,wBAAwB,CAAA;AAEhE,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC,wBAAwB,CAAC,CAE1F;AAED,wBAAgB,MAAM,CACpB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAC/D,OAAO,GAAE,oBAAyB,GACjC,aAAa,CAAC,wBAAwB,CAAC,CAEzC;AAED,wBAAgB,8BAA8B,CAC5C,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,MAAM,GACjB,SAAS,eAAe,EAAE,CAQ5B;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA;IACjB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,wBAAwB,CAAC,CAAA;CAC5D,GAAG,eAAe,CAqBlB;AAED,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMxF;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAKrD;AAuKD,eAAO,MAAM,yBAAyB,
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAGV,YAAY,EACZ,aAAa,EACb,oBAAoB,EACrB,MAAM,oBAAoB,CAAA;AAqH3B,OAAO,KAAK,EAAe,GAAG,EAAa,MAAM,aAAa,CAAA;AAG9D,MAAM,WAAW,wBAAwB;IACvC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACrC;AAED,eAAO,MAAM,2BAA2B,wBAAwB,CAAA;AAEhE,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC,wBAAwB,CAAC,CAE1F;AAED,wBAAgB,MAAM,CACpB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAC/D,OAAO,GAAE,oBAAyB,GACjC,aAAa,CAAC,wBAAwB,CAAC,CAEzC;AAED,wBAAgB,8BAA8B,CAC5C,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,MAAM,GACjB,SAAS,eAAe,EAAE,CAQ5B;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA;IACjB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,wBAAwB,CAAC,CAAA;CAC5D,GAAG,eAAe,CAqBlB;AAED,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMxF;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAKrD;AAuKD,eAAO,MAAM,yBAAyB,wCAkEpC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sixb/pg",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20",
|
|
4
4
|
"description": "PostgreSQL storage provider for Sixb",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sixb",
|
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
"postgres": "^3.4.5"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@sixb/core": "0.1.
|
|
43
|
+
"@sixb/core": "0.1.20"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@sixb/core": "0.1.
|
|
46
|
+
"@sixb/core": "0.1.20",
|
|
47
47
|
"@types/bun": "latest",
|
|
48
48
|
"typescript": "^5.7.0"
|
|
49
49
|
},
|
|
@@ -234,7 +234,6 @@ export class PgAuthStorage implements AuthStorage {
|
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
await validateCompleteSessionInput(tx, projectId, input.session)
|
|
237
|
-
assertSignInSessionAudience(projectId, input.session.audience, magicLink.audience)
|
|
238
237
|
|
|
239
238
|
let newUserId: string | undefined
|
|
240
239
|
if (shouldCreateUser) {
|
|
@@ -394,7 +393,6 @@ export class PgAuthStorage implements AuthStorage {
|
|
|
394
393
|
}
|
|
395
394
|
|
|
396
395
|
await validateCompleteSessionInput(tx, projectId, input.session)
|
|
397
|
-
assertSignInSessionAudience(projectId, input.session.audience, attempt.audience)
|
|
398
396
|
|
|
399
397
|
let newUserId: string | undefined
|
|
400
398
|
if (shouldCreateUser) {
|
|
@@ -719,17 +717,13 @@ export class PgAuthStorage implements AuthStorage {
|
|
|
719
717
|
readonly userId: string
|
|
720
718
|
}
|
|
721
719
|
): Promise<SessionRecord> {
|
|
722
|
-
await lockAdvisoryKeys(sql, [
|
|
723
|
-
authLockKey("sessions", input.projectId, input.userId),
|
|
724
|
-
authLockKey("sessions", input.projectId, input.userId, input.session.audience),
|
|
725
|
-
])
|
|
720
|
+
await lockAdvisoryKeys(sql, [authLockKey("sessions", input.projectId, input.userId)])
|
|
726
721
|
|
|
727
722
|
return createSession(sql, {
|
|
728
723
|
id: input.session.id,
|
|
729
724
|
projectId: input.projectId,
|
|
730
725
|
userId: input.userId,
|
|
731
726
|
strategyId: input.strategyId,
|
|
732
|
-
audience: input.session.audience,
|
|
733
727
|
tokenHash: input.session.tokenHash,
|
|
734
728
|
createdAt: input.session.createdAt,
|
|
735
729
|
expiresAt: input.session.expiresAt,
|
|
@@ -795,21 +789,6 @@ export class PgAuthStorage implements AuthStorage {
|
|
|
795
789
|
}
|
|
796
790
|
}
|
|
797
791
|
|
|
798
|
-
function assertSignInSessionAudience(
|
|
799
|
-
projectId: string,
|
|
800
|
-
sessionAudience: string,
|
|
801
|
-
storedAudience: string
|
|
802
|
-
): void {
|
|
803
|
-
if (sessionAudience === storedAudience) {
|
|
804
|
-
return
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
throw new AuthStorageError(
|
|
808
|
-
"invalid_input",
|
|
809
|
-
`[Sixb] Sign-in session audience '${sessionAudience}' does not match stored auth audience '${storedAudience}' for project '${projectId}'.`
|
|
810
|
-
)
|
|
811
|
-
}
|
|
812
|
-
|
|
813
792
|
function assertCompletableDeviceAuthorization(
|
|
814
793
|
authorization: DeviceAuthorizationRecord,
|
|
815
794
|
input: CompleteDeviceAuthorizationInput
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { resolveAuthSessionAudience } from "@sixb/core"
|
|
2
1
|
import type {
|
|
3
2
|
AuthMagicLinkStore,
|
|
4
3
|
CreateAuthMagicLinkInput,
|
|
@@ -31,7 +30,6 @@ export class PgAuthMagicLinkStore implements AuthMagicLinkStore {
|
|
|
31
30
|
const id = assertNonEmpty(input.id, "Magic link id")
|
|
32
31
|
const projectId = assertNonEmpty(input.projectId, "Project id")
|
|
33
32
|
const strategyId = assertNonEmpty(input.strategyId, "Strategy id")
|
|
34
|
-
const audience = resolveAuthSessionAudience(input.audience)
|
|
35
33
|
const email = normalizeEmail(input.email)
|
|
36
34
|
const tokenHash = assertNonEmpty(input.tokenHash, "Magic link token hash")
|
|
37
35
|
|
|
@@ -56,7 +54,6 @@ export class PgAuthMagicLinkStore implements AuthMagicLinkStore {
|
|
|
56
54
|
project_id,
|
|
57
55
|
id,
|
|
58
56
|
strategy_id,
|
|
59
|
-
audience,
|
|
60
57
|
email,
|
|
61
58
|
token_hash,
|
|
62
59
|
return_to,
|
|
@@ -66,7 +63,6 @@ export class PgAuthMagicLinkStore implements AuthMagicLinkStore {
|
|
|
66
63
|
${projectId},
|
|
67
64
|
${id},
|
|
68
65
|
${strategyId},
|
|
69
|
-
${audience},
|
|
70
66
|
${email},
|
|
71
67
|
${tokenHash},
|
|
72
68
|
${input.returnTo ?? null},
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { resolveAuthSessionAudience } from "@sixb/core"
|
|
2
1
|
import type {
|
|
3
2
|
AuthOidcAuthorizationAttemptStore,
|
|
4
3
|
CreateOidcAuthorizationAttemptInput,
|
|
@@ -25,7 +24,6 @@ export class PgAuthOidcAuthorizationAttemptStore implements AuthOidcAuthorizatio
|
|
|
25
24
|
const id = assertNonEmpty(input.id, "OIDC authorization attempt id")
|
|
26
25
|
const projectId = assertNonEmpty(input.projectId, "Project id")
|
|
27
26
|
const strategyId = assertNonEmpty(input.strategyId, "Strategy id")
|
|
28
|
-
const audience = resolveAuthSessionAudience(input.audience)
|
|
29
27
|
const stateHash = assertNonEmpty(input.stateHash, "OIDC state hash")
|
|
30
28
|
const nonceHash = assertNonEmpty(input.nonceHash, "OIDC nonce hash")
|
|
31
29
|
const codeVerifier = assertNonEmpty(input.codeVerifier, "OIDC code verifier")
|
|
@@ -43,7 +41,6 @@ export class PgAuthOidcAuthorizationAttemptStore implements AuthOidcAuthorizatio
|
|
|
43
41
|
project_id,
|
|
44
42
|
id,
|
|
45
43
|
strategy_id,
|
|
46
|
-
audience,
|
|
47
44
|
state_hash,
|
|
48
45
|
nonce_hash,
|
|
49
46
|
code_verifier,
|
|
@@ -54,7 +51,6 @@ export class PgAuthOidcAuthorizationAttemptStore implements AuthOidcAuthorizatio
|
|
|
54
51
|
${projectId},
|
|
55
52
|
${id},
|
|
56
53
|
${strategyId},
|
|
57
|
-
${audience},
|
|
58
54
|
${stateHash},
|
|
59
55
|
${nonceHash},
|
|
60
56
|
${codeVerifier},
|
package/src/auth-storage/rows.ts
CHANGED
|
@@ -67,7 +67,6 @@ export interface PgAuthSessionRow {
|
|
|
67
67
|
readonly id: string
|
|
68
68
|
readonly user_id: string
|
|
69
69
|
readonly strategy_id: string
|
|
70
|
-
readonly audience: SessionRecord["audience"]
|
|
71
70
|
readonly token_hash: string
|
|
72
71
|
readonly created_at: PgDate
|
|
73
72
|
readonly expires_at: PgDate
|
|
@@ -132,7 +131,6 @@ export interface PgAuthMagicLinkRow {
|
|
|
132
131
|
readonly project_id: string
|
|
133
132
|
readonly id: string
|
|
134
133
|
readonly strategy_id: string
|
|
135
|
-
readonly audience: MagicLinkRecord["audience"]
|
|
136
134
|
readonly email: string
|
|
137
135
|
readonly token_hash: string
|
|
138
136
|
readonly return_to: string | null
|
|
@@ -146,7 +144,6 @@ export interface PgAuthOidcAttemptRow {
|
|
|
146
144
|
readonly project_id: string
|
|
147
145
|
readonly id: string
|
|
148
146
|
readonly strategy_id: string
|
|
149
|
-
readonly audience: OidcAuthorizationAttemptRecord["audience"]
|
|
150
147
|
readonly state_hash: string
|
|
151
148
|
readonly nonce_hash: string
|
|
152
149
|
readonly code_verifier: string
|
|
@@ -229,7 +226,6 @@ export function rowToSessionRecord(row: PgAuthSessionRow): SessionRecord {
|
|
|
229
226
|
projectId: row.project_id,
|
|
230
227
|
userId: row.user_id,
|
|
231
228
|
strategyId: row.strategy_id,
|
|
232
|
-
audience: row.audience,
|
|
233
229
|
tokenHash: row.token_hash,
|
|
234
230
|
createdAt: toDate(row.created_at),
|
|
235
231
|
expiresAt: toDate(row.expires_at),
|
|
@@ -306,7 +302,6 @@ export function rowToMagicLinkRecord(row: PgAuthMagicLinkRow): MagicLinkRecord {
|
|
|
306
302
|
id: row.id,
|
|
307
303
|
projectId: row.project_id,
|
|
308
304
|
strategyId: row.strategy_id,
|
|
309
|
-
audience: row.audience,
|
|
310
305
|
email: row.email,
|
|
311
306
|
tokenHash: row.token_hash,
|
|
312
307
|
returnTo: row.return_to ?? undefined,
|
|
@@ -324,7 +319,6 @@ export function rowToOidcAuthorizationAttemptRecord(
|
|
|
324
319
|
id: row.id,
|
|
325
320
|
projectId: row.project_id,
|
|
326
321
|
strategyId: row.strategy_id,
|
|
327
|
-
audience: row.audience,
|
|
328
322
|
stateHash: row.state_hash,
|
|
329
323
|
nonceHash: row.nonce_hash,
|
|
330
324
|
codeVerifier: row.code_verifier,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { AuthSessionAudience } from "@sixb/core"
|
|
2
1
|
import type {
|
|
3
2
|
AuthSessionStore,
|
|
4
3
|
CreateAuthSessionInput,
|
|
@@ -38,28 +37,6 @@ export class PgAuthSessionStore implements AuthSessionStore {
|
|
|
38
37
|
return getSessionById(this.sql, params)
|
|
39
38
|
}
|
|
40
39
|
|
|
41
|
-
async getActiveByUserId(params: {
|
|
42
|
-
readonly projectId: string
|
|
43
|
-
readonly userId: string
|
|
44
|
-
readonly audience: AuthSessionAudience
|
|
45
|
-
readonly now: Date
|
|
46
|
-
}): Promise<SessionRecord | null> {
|
|
47
|
-
const [row] = await this.sql<PgAuthSessionRow[]>`
|
|
48
|
-
SELECT *
|
|
49
|
-
FROM auth_sessions
|
|
50
|
-
WHERE project_id = ${params.projectId}
|
|
51
|
-
AND user_id = ${params.userId}
|
|
52
|
-
AND audience = ${params.audience}
|
|
53
|
-
AND revoked_at IS NULL
|
|
54
|
-
AND expires_at > ${params.now}
|
|
55
|
-
AND (absolute_expires_at IS NULL OR absolute_expires_at > ${params.now})
|
|
56
|
-
ORDER BY created_at DESC, id DESC
|
|
57
|
-
LIMIT 1
|
|
58
|
-
`
|
|
59
|
-
|
|
60
|
-
return row ? rowToSessionRecord(row) : null
|
|
61
|
-
}
|
|
62
|
-
|
|
63
40
|
async listActiveByUserId(params: {
|
|
64
41
|
readonly projectId: string
|
|
65
42
|
readonly userId: string
|
|
@@ -82,7 +59,6 @@ export class PgAuthSessionStore implements AuthSessionStore {
|
|
|
82
59
|
async findValidByTokenHash(params: {
|
|
83
60
|
readonly projectId: string
|
|
84
61
|
readonly id: string
|
|
85
|
-
readonly audience: AuthSessionAudience
|
|
86
62
|
readonly tokenHash: string
|
|
87
63
|
readonly now: Date
|
|
88
64
|
}): Promise<SessionRecord | null> {
|
|
@@ -91,7 +67,6 @@ export class PgAuthSessionStore implements AuthSessionStore {
|
|
|
91
67
|
if (
|
|
92
68
|
!row ||
|
|
93
69
|
row.refresh_token_hash !== null ||
|
|
94
|
-
row.audience !== params.audience ||
|
|
95
70
|
row.token_hash !== params.tokenHash ||
|
|
96
71
|
!isLiveSessionRow(row, params.now)
|
|
97
72
|
) {
|
|
@@ -169,7 +144,6 @@ export class PgAuthSessionStore implements AuthSessionStore {
|
|
|
169
144
|
async renewIfValid(params: {
|
|
170
145
|
readonly projectId: string
|
|
171
146
|
readonly id: string
|
|
172
|
-
readonly audience: AuthSessionAudience
|
|
173
147
|
readonly tokenHash: string
|
|
174
148
|
readonly now: Date
|
|
175
149
|
readonly expiresAt: Date
|
|
@@ -186,7 +160,6 @@ export class PgAuthSessionStore implements AuthSessionStore {
|
|
|
186
160
|
last_seen_at = ${params.now}
|
|
187
161
|
WHERE project_id = ${params.projectId}
|
|
188
162
|
AND id = ${params.id}
|
|
189
|
-
AND audience = ${params.audience}
|
|
190
163
|
AND token_hash = ${params.tokenHash}
|
|
191
164
|
AND refresh_token_hash IS NULL
|
|
192
165
|
AND revoked_at IS NULL
|
|
@@ -228,15 +201,10 @@ export class PgAuthSessionStore implements AuthSessionStore {
|
|
|
228
201
|
async revokeActiveForUser(params: {
|
|
229
202
|
readonly projectId: string
|
|
230
203
|
readonly userId: string
|
|
231
|
-
readonly audience?: AuthSessionAudience
|
|
232
204
|
readonly revokedAt: Date
|
|
233
205
|
}): Promise<readonly SessionRecord[]> {
|
|
234
206
|
return runPgTransaction(this.sql, async (tx) => {
|
|
235
|
-
|
|
236
|
-
if (params.audience) {
|
|
237
|
-
locks.push(authLockKey("sessions", params.projectId, params.userId, params.audience))
|
|
238
|
-
}
|
|
239
|
-
await lockAdvisoryKeys(tx, locks)
|
|
207
|
+
await lockAdvisoryKeys(tx, [authLockKey("sessions", params.projectId, params.userId)])
|
|
240
208
|
return revokeActiveSessionsForUser(tx, params)
|
|
241
209
|
})
|
|
242
210
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Principal } from "@sixb/core"
|
|
2
2
|
import type {
|
|
3
3
|
CompleteAuthSessionInput,
|
|
4
4
|
CreateAuthSessionInput,
|
|
@@ -442,7 +442,6 @@ export async function validateCompleteSessionInput(
|
|
|
442
442
|
session: CompleteAuthSessionInput
|
|
443
443
|
): Promise<void> {
|
|
444
444
|
const sessionId = assertNonEmpty(session.id, "Session id")
|
|
445
|
-
assertNonEmpty(session.audience, "Session audience")
|
|
446
445
|
assertNonEmpty(session.tokenHash, "Session token hash")
|
|
447
446
|
await assertSessionIdAvailable(sql, projectId, sessionId)
|
|
448
447
|
}
|
|
@@ -468,7 +467,6 @@ export async function createSession(
|
|
|
468
467
|
const projectId = assertNonEmpty(input.projectId, "Project id")
|
|
469
468
|
const userId = assertNonEmpty(input.userId, "User id")
|
|
470
469
|
const strategyId = assertNonEmpty(input.strategyId, "Strategy id")
|
|
471
|
-
const audience = assertNonEmpty(input.audience, "Session audience")
|
|
472
470
|
const tokenHash = assertNonEmpty(input.tokenHash, "Session token hash")
|
|
473
471
|
|
|
474
472
|
await requireUserById(sql, { projectId, id: userId })
|
|
@@ -481,7 +479,6 @@ export async function createSession(
|
|
|
481
479
|
id,
|
|
482
480
|
user_id,
|
|
483
481
|
strategy_id,
|
|
484
|
-
audience,
|
|
485
482
|
token_hash,
|
|
486
483
|
created_at,
|
|
487
484
|
expires_at,
|
|
@@ -496,7 +493,6 @@ export async function createSession(
|
|
|
496
493
|
${id},
|
|
497
494
|
${userId},
|
|
498
495
|
${strategyId},
|
|
499
|
-
${audience},
|
|
500
496
|
${tokenHash},
|
|
501
497
|
${input.createdAt},
|
|
502
498
|
${input.expiresAt},
|
|
@@ -525,13 +521,10 @@ export async function revokeActiveSessionsForUser(
|
|
|
525
521
|
params: {
|
|
526
522
|
readonly projectId: string
|
|
527
523
|
readonly userId: string
|
|
528
|
-
readonly audience?: AuthSessionAudience
|
|
529
524
|
readonly revokedAt: Date
|
|
530
525
|
}
|
|
531
526
|
): Promise<readonly SessionRecord[]> {
|
|
532
|
-
const rows =
|
|
533
|
-
params.audience === undefined
|
|
534
|
-
? await sql<PgAuthSessionRow[]>`
|
|
527
|
+
const rows = await sql<PgAuthSessionRow[]>`
|
|
535
528
|
SELECT *
|
|
536
529
|
FROM auth_sessions
|
|
537
530
|
WHERE project_id = ${params.projectId}
|
|
@@ -542,41 +535,16 @@ export async function revokeActiveSessionsForUser(
|
|
|
542
535
|
ORDER BY created_at ASC, id ASC
|
|
543
536
|
FOR UPDATE
|
|
544
537
|
`
|
|
545
|
-
: await sql<PgAuthSessionRow[]>`
|
|
546
|
-
SELECT *
|
|
547
|
-
FROM auth_sessions
|
|
548
|
-
WHERE project_id = ${params.projectId}
|
|
549
|
-
AND user_id = ${params.userId}
|
|
550
|
-
AND audience = ${params.audience}
|
|
551
|
-
AND revoked_at IS NULL
|
|
552
|
-
AND expires_at > ${params.revokedAt}
|
|
553
|
-
AND (absolute_expires_at IS NULL OR absolute_expires_at > ${params.revokedAt})
|
|
554
|
-
ORDER BY created_at ASC, id ASC
|
|
555
|
-
FOR UPDATE
|
|
556
|
-
`
|
|
557
538
|
|
|
558
|
-
|
|
559
|
-
await sql`
|
|
560
|
-
UPDATE auth_sessions
|
|
561
|
-
SET revoked_at = ${params.revokedAt}
|
|
562
|
-
WHERE project_id = ${params.projectId}
|
|
563
|
-
AND user_id = ${params.userId}
|
|
564
|
-
AND revoked_at IS NULL
|
|
565
|
-
AND expires_at > ${params.revokedAt}
|
|
566
|
-
AND (absolute_expires_at IS NULL OR absolute_expires_at > ${params.revokedAt})
|
|
567
|
-
`
|
|
568
|
-
} else {
|
|
569
|
-
await sql`
|
|
539
|
+
await sql`
|
|
570
540
|
UPDATE auth_sessions
|
|
571
541
|
SET revoked_at = ${params.revokedAt}
|
|
572
542
|
WHERE project_id = ${params.projectId}
|
|
573
543
|
AND user_id = ${params.userId}
|
|
574
|
-
AND audience = ${params.audience}
|
|
575
544
|
AND revoked_at IS NULL
|
|
576
545
|
AND expires_at > ${params.revokedAt}
|
|
577
546
|
AND (absolute_expires_at IS NULL OR absolute_expires_at > ${params.revokedAt})
|
|
578
547
|
`
|
|
579
|
-
}
|
|
580
548
|
|
|
581
549
|
return rows.map((row) =>
|
|
582
550
|
rowToSessionRecord({
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
-- A project has one browser app, so sessions, magic links and sign-in attempts no longer name the
|
|
2
|
+
-- one they belong to. Atlas's browser sessions end here: their cookie is no longer read. Native
|
|
3
|
+
-- sessions carried Atlas's name only because the column needed a value, so they stay.
|
|
4
|
+
UPDATE auth_sessions
|
|
5
|
+
SET revoked_at = now()
|
|
6
|
+
WHERE audience = 'atlas'
|
|
7
|
+
AND refresh_token_hash IS NULL
|
|
8
|
+
AND revoked_at IS NULL;
|
|
9
|
+
|
|
10
|
+
-- Dropping the column drops the two indexes that name it.
|
|
11
|
+
ALTER TABLE auth_sessions DROP COLUMN audience;
|
|
12
|
+
CREATE INDEX idx_auth_sessions_user_active
|
|
13
|
+
ON auth_sessions (project_id, user_id, expires_at DESC, created_at DESC, id DESC)
|
|
14
|
+
WHERE revoked_at IS NULL;
|
|
15
|
+
CREATE INDEX idx_auth_sessions_user_created
|
|
16
|
+
ON auth_sessions (project_id, user_id, created_at DESC, id DESC);
|
|
17
|
+
|
|
18
|
+
ALTER TABLE auth_magic_links DROP COLUMN audience;
|
|
19
|
+
ALTER TABLE auth_oidc_authorization_attempts DROP COLUMN audience;
|
package/src/migrations.ts
CHANGED
|
@@ -432,6 +432,7 @@ export const postgresStorageMigrations = defineMigrations<PostgresMigrationConte
|
|
|
432
432
|
pgSql("059-file-download-grants", fileDownloadGrantsSql),
|
|
433
433
|
pgSql("060-drained-source-versions", drainedSourceVersionsSql),
|
|
434
434
|
pgSql("061-terminal-action-runs", terminalActionRunsSql),
|
|
435
|
+
pgSql("062-drop-auth-audience", dropAuthAudienceSql),
|
|
435
436
|
],
|
|
436
437
|
})
|
|
437
438
|
|
|
@@ -461,3 +462,4 @@ import drainedSourceVersionsSql from "./migrations/060-drained-source-versions.s
|
|
|
461
462
|
type: "text",
|
|
462
463
|
}
|
|
463
464
|
import terminalActionRunsSql from "./migrations/061-terminal-action-runs.sql" with { type: "text" }
|
|
465
|
+
import dropAuthAudienceSql from "./migrations/062-drop-auth-audience.sql" with { type: "text" }
|