packages
pds
src
account-manager
config
lexicon
···
1
1
+
/handle-monitor-incidents/
2
2
+
/handle-monitor*
3
3
+
/handle-prober*
4
4
+
*.log.json
5
5
+
/ngrok-pds
6
6
+
/pds-local
7
7
+
/.gitmodules
8
8
+
1
9
node_modules
2
10
lerna-debug.log
3
11
npm-debug.log
···
41
41
readonly serviceDid: string,
42
42
readonly serviceHandleDomains: string[],
43
43
db: AccountManagerDbConfig,
44
44
+
readonly jwtAccessLifetime: string = '120mins',
45
45
+
readonly jwtReauthLifetime: string = '30days',
44
46
) {
45
47
this.db = getDb(db.accountDbLoc, db.disableWalAutoCheckpoint)
46
48
}
···
315
317
jwtKey: this.jwtKey,
316
318
serviceDid: this.serviceDid,
317
319
scope: AuthScope.Access,
320
320
+
expiresIn: this.jwtAccessLifetime,
318
321
})
319
322
320
323
await this.createAccount({ ...opts, refreshJwt })
···
372
375
jwtKey: this.jwtKey,
373
376
serviceDid: this.serviceDid,
374
377
scope: auth.formatScope(appPassword, isSoftDeleted),
378
378
+
expiresIn: this.jwtAccessLifetime,
375
379
jid,
376
380
})
377
381
// For soft deleted accounts don't store refresh token so that it can't be rotated.
···
385
389
async createReauthJwt(did: string, jid?: string): Promise<string> {
386
390
return auth.createReauthToken({
387
391
did,
388
388
-
jid,
389
392
jwtKey: this.jwtKey,
390
393
serviceDid: this.serviceDid,
394
394
+
jid,
395
395
+
expiresIn: this.jwtReauthLifetime,
391
396
})
392
397
}
393
398
···
436
441
serviceDid: this.serviceDid,
437
442
scope: auth.formatScope(token.appPassword),
438
443
jti: nextId,
444
444
+
expiresIn: this.jwtAccessLifetime,
439
445
jid: token.loginJid,
440
446
})
441
447
···
91
91
92
92
export const createReauthToken = (opts: {
93
93
did: string
94
94
-
jid?: string
95
94
jwtKey: KeyObject
96
95
serviceDid: string
96
96
+
jid?: string
97
97
+
expiresIn?: string | number
97
98
}): Promise<string> => {
98
98
-
const { did, jid, jwtKey, serviceDid } = opts
99
99
+
const { did, jwtKey, serviceDid, jid, expiresIn = '30days' } = opts
99
100
const claims: Record<string, unknown> = { scope: AuthScope.Reauth }
100
101
if (jid !== undefined) claims.jid = jid
101
101
-
return new jose.SignJWT(claims)
102
102
-
.setProtectedHeader({ typ: 'reauth+jwt', alg: 'HS256' })
102
102
+
const signer = new jose.SignJWT(claims)
103
103
+
.setProtectedHeader({
104
104
+
typ: 'reauth+jwt',
105
105
+
alg: 'HS256',
106
106
+
})
103
107
.setAudience(serviceDid)
104
108
.setSubject(did)
105
109
.setJti(getRefreshTokenId())
106
110
.setIssuedAt()
107
107
-
.setExpirationTime('30days')
108
108
-
.sign(jwtKey)
111
111
+
.setExpirationTime(expiresIn)
112
112
+
return signer.sign(jwtKey)
109
113
}
110
114
111
115
// @NOTE unsafe for verification, should only be used w/ direct output from createRefreshToken() or createTokens()
···
69
69
maxImportSize: env.maxImportSize,
70
70
blobUploadLimit: env.blobUploadLimit ?? 5 * 1024 * 1024, // 5mb
71
71
devMode: env.devMode ?? false,
72
72
+
jwtAccessLifetime: env.jwtAccessLifetime ?? '120mins',
73
73
+
jwtReauthLifetime: env.jwtReauthLifetime ?? '30days',
72
74
}
73
75
74
76
const dbLoc = (name: string) => {
···
471
473
blobUploadLimit: number
472
474
contactEmailAddress?: string
473
475
devMode: boolean
476
476
+
jwtAccessLifetime: string
477
477
+
jwtReauthLifetime: string
474
478
}
475
479
476
480
export type DatabaseConfig = {
···
130
130
// secrets
131
131
dpopSecret: envStr('PDS_DPOP_SECRET'),
132
132
jwtSecret: envStr('PDS_JWT_SECRET'),
133
133
+
// JWT token lifetimes (jose duration strings, e.g. '120mins', '2mins', '30days')
134
134
+
jwtAccessLifetime: envStr('PDS_JWT_ACCESS_LIFETIME'),
135
135
+
jwtReauthLifetime: envStr('PDS_JWT_REAUTH_LIFETIME'),
133
136
adminPassword: envStr('PDS_ADMIN_PASSWORD'),
134
137
entrywayAdminToken: envStr('PDS_ENTRYWAY_ADMIN_TOKEN'),
135
138
···
254
254
cfg.service.did,
255
255
cfg.identity.serviceHandleDomains,
256
256
cfg.db,
257
257
+
cfg.service.jwtAccessLifetime,
258
258
+
cfg.service.jwtReauthLifetime,
257
259
)
258
260
await accountManager.migrateOrThrow()
259
261
···
238
238
import * as EuWsocialQuickloginSilentReauth from './types/eu/wsocial/quicklogin/silentReauth.js'
239
239
import * as EuWsocialServerAllocateWidForAccount from './types/eu/wsocial/server/allocateWidForAccount.js'
240
240
import * as EuWsocialServerCheckHandleAvailability from './types/eu/wsocial/server/checkHandleAvailability.js'
241
241
-
import * as EuWsocialServerGetReauthToken from './types/eu/wsocial/server/getReauthToken.js'
242
241
import * as EuWsocialServerGetCapabilities from './types/eu/wsocial/server/getCapabilities.js'
242
242
+
import * as EuWsocialServerGetReauthToken from './types/eu/wsocial/server/getReauthToken.js'
243
243
import * as EuWsocialServerRequestAccountDelete from './types/eu/wsocial/server/requestAccountDelete.js'
244
244
import * as IoTrustanchorAdminClearInventory from './types/io/trustanchor/admin/clearInventory.js'
245
245
import * as IoTrustanchorAdminCreateAccountSession from './types/io/trustanchor/admin/createAccountSession.js'
···
3526
3526
return this._server.xrpc.method(nsid, cfg)
3527
3527
}
3528
3528
3529
3529
-
getReauthToken<A extends Auth = void>(
3529
3529
+
getCapabilities<A extends Auth = void>(
3530
3530
cfg: MethodConfigOrHandler<
3531
3531
A,
3532
3532
-
EuWsocialServerGetReauthToken.QueryParams,
3533
3533
-
EuWsocialServerGetReauthToken.HandlerInput,
3534
3534
-
EuWsocialServerGetReauthToken.HandlerOutput
3532
3532
+
EuWsocialServerGetCapabilities.QueryParams,
3533
3533
+
EuWsocialServerGetCapabilities.HandlerInput,
3534
3534
+
EuWsocialServerGetCapabilities.HandlerOutput
3535
3535
>,
3536
3536
) {
3537
3537
-
const nsid = 'eu.wsocial.server.getReauthToken' // @ts-ignore
3537
3537
+
const nsid = 'eu.wsocial.server.getCapabilities' // @ts-ignore
3538
3538
return this._server.xrpc.method(nsid, cfg)
3539
3539
}
3540
3540
3541
3541
-
getCapabilities<A extends Auth = void>(
3541
3541
+
getReauthToken<A extends Auth = void>(
3542
3542
cfg: MethodConfigOrHandler<
3543
3543
A,
3544
3544
-
EuWsocialServerGetCapabilities.QueryParams,
3545
3545
-
EuWsocialServerGetCapabilities.HandlerInput,
3546
3546
-
EuWsocialServerGetCapabilities.HandlerOutput
3544
3544
+
EuWsocialServerGetReauthToken.QueryParams,
3545
3545
+
EuWsocialServerGetReauthToken.HandlerInput,
3546
3546
+
EuWsocialServerGetReauthToken.HandlerOutput
3547
3547
>,
3548
3548
) {
3549
3549
-
const nsid = 'eu.wsocial.server.getCapabilities' // @ts-ignore
3549
3549
+
const nsid = 'eu.wsocial.server.getReauthToken' // @ts-ignore
3550
3550
return this._server.xrpc.method(nsid, cfg)
3551
3551
}
3552
3552
···
16542
16542
},
16543
16543
},
16544
16544
},
16545
16545
-
EuWsocialServerGetReauthToken: {
16545
16545
+
EuWsocialServerGetCapabilities: {
16546
16546
lexicon: 1,
16547
16547
-
id: 'eu.wsocial.server.getReauthToken',
16547
16547
+
id: 'eu.wsocial.server.getCapabilities',
16548
16548
defs: {
16549
16549
main: {
16550
16550
type: 'query',
16551
16551
description:
16552
16552
-
'Returns a re-auth token for the current session. Call once after login and store in device secure storage. Valid for 30 days from the time of issue. Present to eu.wsocial.quicklogin.silentReauth to silently resume a dead session without a full WID scan or password prompt.',
16552
16552
+
'Return W Social-specific capability flags for this PDS deployment. No authentication required. Values are static per deployment (env-var driven).',
16553
16553
output: {
16554
16554
encoding: 'application/json',
16555
16555
schema: {
16556
16556
type: 'object',
16557
16557
-
required: ['reauthJwt'],
16557
16557
+
required: ['unverifiedLikesAllowed', 'unverifiedFollowsAllowed'],
16558
16558
properties: {
16559
16559
-
reauthJwt: {
16560
16560
-
type: 'string',
16561
16561
-
description: 'Re-auth token. Store in device secure storage.',
16559
16559
+
unverifiedLikesAllowed: {
16560
16560
+
type: 'boolean',
16561
16561
+
description:
16562
16562
+
'When true, unverified accounts may create and delete app.bsky.feed.like records.',
16563
16563
+
},
16564
16564
+
unverifiedFollowsAllowed: {
16565
16565
+
type: 'boolean',
16566
16566
+
description:
16567
16567
+
'When true, unverified accounts may create and delete app.bsky.graph.follow records.',
16562
16568
},
16563
16569
},
16564
16570
},
16565
16571
},
16566
16572
},
16567
16573
},
16568
16568
-
},
16569
16569
-
EuWsocialServerGetCapabilities: {
16574
16574
+
},
16575
16575
+
EuWsocialServerGetReauthToken: {
16570
16576
lexicon: 1,
16571
16571
-
id: 'eu.wsocial.server.getCapabilities',
16577
16577
+
id: 'eu.wsocial.server.getReauthToken',
16572
16578
defs: {
16573
16579
main: {
16574
16580
type: 'query',
16575
16581
description:
16576
16576
-
'Return W Social-specific capability flags for this PDS deployment. No authentication required. Values are static per deployment (env-var driven).',
16582
16582
+
'Returns a re-auth token for the current session. Call once after login and store in device secure storage. Valid for 30 days from the time of issue. Present to eu.wsocial.quicklogin.silentReauth to silently resume a dead session without a full WID scan or password prompt.',
16577
16583
output: {
16578
16584
encoding: 'application/json',
16579
16585
schema: {
16580
16586
type: 'object',
16581
16581
-
required: ['unverifiedLikesAllowed', 'unverifiedFollowsAllowed'],
16587
16587
+
required: ['reauthJwt'],
16582
16588
properties: {
16583
16583
-
unverifiedLikesAllowed: {
16584
16584
-
type: 'boolean',
16585
16585
-
description:
16586
16586
-
'When true, unverified accounts may create and delete app.bsky.feed.like records.',
16587
16587
-
},
16588
16588
-
unverifiedFollowsAllowed: {
16589
16589
-
type: 'boolean',
16590
16590
-
description:
16591
16591
-
'When true, unverified accounts may create and delete app.bsky.graph.follow records.',
16589
16589
+
reauthJwt: {
16590
16590
+
type: 'string',
16591
16591
+
description: 'Re-auth token. Store in device secure storage.',
16592
16592
},
16593
16593
},
16594
16594
},
···
23393
23393
'eu.wsocial.server.allocateWidForAccount',
23394
23394
EuWsocialServerCheckHandleAvailability:
23395
23395
'eu.wsocial.server.checkHandleAvailability',
23396
23396
-
EuWsocialServerGetReauthToken: 'eu.wsocial.server.getReauthToken',
23397
23396
EuWsocialServerGetCapabilities: 'eu.wsocial.server.getCapabilities',
23397
23397
+
EuWsocialServerGetReauthToken: 'eu.wsocial.server.getReauthToken',
23398
23398
EuWsocialServerRequestAccountDelete: 'eu.wsocial.server.requestAccountDelete',
23399
23399
IoTrustanchorAdminClearInventory: 'io.trustanchor.admin.clearInventory',
23400
23400
IoTrustanchorAdminCreateAccountSession: