Skip to content

Commit ef06c80

Browse files
committed
I think that's the session store
1 parent 7d69561 commit ef06c80

5 files changed

Lines changed: 64 additions & 21 deletions

File tree

modules/cache.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { provider } from 'std-env'
44

55
// Storage key for fetch cache - must match shared/utils/fetch-cache-config.ts
66
const FETCH_CACHE_STORAGE_BASE = 'fetch-cache'
7+
// Storage key for OAuth cache - must match server/utils/atproto/storage.ts
8+
const OAUTH_CACHE_STORAGE_BASE = 'atproto:oauth'
79

810
export default defineNuxtModule({
911
meta: {
@@ -37,6 +39,11 @@ export default defineNuxtModule({
3739
...nitroConfig.storage[FETCH_CACHE_STORAGE_BASE],
3840
driver: 'vercel-runtime-cache',
3941
}
42+
43+
nitroConfig.storage[OAUTH_CACHE_STORAGE_BASE] = {
44+
...nitroConfig.storage[OAUTH_CACHE_STORAGE_BASE],
45+
driver: 'vercel-runtime-cache',
46+
}
4047
}
4148

4249
const env = process.env.VERCEL_ENV
Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,43 @@
11
import type { NodeSavedSession, NodeSavedSessionStore } from '@atproto/oauth-client-node'
22
import type { UserServerSession } from '#shared/types/userSession'
33
import type { SessionManager } from 'h3'
4+
import { OAUTH_CACHE_STORAGE_BASE } from '#server/utils/atproto/storage'
45

56
export class OAuthSessionStore implements NodeSavedSessionStore {
6-
private readonly session: SessionManager<UserServerSession>
7+
private readonly serverSession: SessionManager<UserServerSession>
8+
private readonly storage = useStorage(OAUTH_CACHE_STORAGE_BASE)
79

810
constructor(session: SessionManager<UserServerSession>) {
9-
this.session = session
11+
this.serverSession = this.serverSession = session
1012
}
1113

12-
async get(): Promise<NodeSavedSession | undefined> {
13-
const sessionData = this.session.data
14-
if (!sessionData) return undefined
15-
return sessionData.oauthSession
14+
private createStorageKey(did: string, sessionId: string) {
15+
return `sessions:${did}:${sessionId}`
1616
}
1717

18-
async set(_key: string, val: NodeSavedSession) {
19-
// We are ignoring the key since the mapping is already done in the session
18+
async get(key: string): Promise<NodeSavedSession | undefined> {
19+
const serverSessionData = this.serverSession.data
20+
if (!serverSessionData) return undefined
21+
if (!serverSessionData.oauthSessionId) {
22+
console.warn('[oauth session store] No oauthSessionId found in session data')
23+
return undefined
24+
}
25+
26+
let session = await this.storage.getItem<NodeSavedSession>(
27+
this.createStorageKey(key, serverSessionData.oauthSessionId),
28+
)
29+
return session ?? undefined
30+
}
31+
32+
async set(key: string, val: NodeSavedSession) {
33+
let sessionId = crypto.randomUUID()
34+
2035
try {
21-
await this.session.update({
22-
oauthSession: val,
36+
await this.serverSession.update({
37+
oauthSessionId: sessionId,
2338
})
39+
40+
await this.storage.setItem<NodeSavedSession>(this.createStorageKey(key, sessionId), val)
2441
} catch (error) {
2542
// Not sure if this has been happening. But helps with debugging
2643
console.error(
@@ -31,9 +48,16 @@ export class OAuthSessionStore implements NodeSavedSessionStore {
3148
}
3249
}
3350

34-
async del() {
35-
await this.session.update({
36-
oauthSession: undefined,
51+
async del(key: string) {
52+
const serverSessionData = this.serverSession.data
53+
if (!serverSessionData) return undefined
54+
if (!serverSessionData.oauthSessionId) {
55+
console.warn('[oauth session store] No oauthSessionId found in session data')
56+
return undefined
57+
}
58+
await this.storage.removeItem(this.createStorageKey(key, serverSessionData.oauthSessionId))
59+
await this.serverSession.update({
60+
oauthSessionId: undefined,
3761
})
3862
}
3963
}

server/utils/atproto/oauth-state-store.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,35 @@
11
import type { NodeSavedState, NodeSavedStateStore } from '@atproto/oauth-client-node'
22
import type { UserServerSession } from '#shared/types/userSession'
33
import type { SessionManager } from 'h3'
4+
import { OAUTH_CACHE_STORAGE_BASE } from '#server/utils/atproto/storage'
45

56
export class OAuthStateStore implements NodeSavedStateStore {
6-
private readonly session: SessionManager<UserServerSession>
7+
private readonly serverSession: SessionManager<UserServerSession>
8+
private readonly storage = useStorage(OAUTH_CACHE_STORAGE_BASE)
79

810
constructor(session: SessionManager<UserServerSession>) {
9-
this.session = session
11+
this.serverSession = session
12+
}
13+
14+
private createAKey(did: string, sessionId: string) {
15+
return `state:${did}:${sessionId}`
1016
}
1117

1218
async get(): Promise<NodeSavedState | undefined> {
13-
const sessionData = this.session.data
14-
if (!sessionData) return undefined
15-
return sessionData.oauthState
19+
const serverSessionData = this.serverSession.data
20+
if (!serverSessionData) return undefined
21+
return serverSessionData.oauthState
1622
}
1723

18-
async set(_key: string, val: NodeSavedState) {
24+
async set(key: string, val: NodeSavedState) {
1925
// We are ignoring the key since the mapping is already done in the session
20-
await this.session.update({
26+
await this.serverSession.update({
2127
oauthState: val,
2228
})
2329
}
2430

2531
async del() {
26-
await this.session.update({
32+
await this.serverSession.update({
2733
oauthState: undefined,
2834
})
2935
}

server/utils/atproto/storage.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { OAuthStateStore } from './oauth-state-store'
33
import { OAuthSessionStore } from './oauth-session-store'
44
import type { UserServerSession } from '#shared/types/userSession'
55

6+
export const OAUTH_CACHE_STORAGE_BASE = 'atproto:oauth'
7+
68
export const useOAuthStorage = (session: SessionManager<UserServerSession>) => {
79
return {
810
stateStore: new OAuthStateStore(session),

shared/types/userSession.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@ export interface UserServerSession {
1414
// multiple did logins per server session
1515
oauthSession?: NodeSavedSession | undefined
1616
oauthState?: NodeSavedState | undefined
17+
// TODO: This todo is a place holder to rememebr to clean this up after this current oauth change
18+
//
19+
// Will most likely be crypto.randomUUID() and the did
20+
oauthSessionId?: string | undefined
1721
}

0 commit comments

Comments
 (0)