-
Notifications
You must be signed in to change notification settings - Fork 554
/
node-oauth-client.ts
88 lines (75 loc) · 2.26 KB
/
node-oauth-client.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import { createHash, randomBytes } from 'node:crypto'
import {
AtprotoHandleResolverNode,
AtprotoHandleResolverNodeOptions,
} from '@atproto-labs/handle-resolver-node'
import { JoseKey } from '@atproto/jwk-jose'
import {
OAuthClient,
OAuthClientFetchMetadataOptions,
OAuthClientOptions,
RuntimeLock,
} from '@atproto/oauth-client'
import { OAuthResponseMode } from '@atproto/oauth-types'
import {
NodeSavedSessionStore,
NodeSavedStateStore,
toDpopKeyStore,
} from './node-dpop-store.js'
export type * from './node-dpop-store.js'
export type { OAuthClientOptions, OAuthResponseMode, RuntimeLock }
export type NodeOAuthClientOptions = Omit<
OAuthClientOptions,
| 'responseMode'
| 'runtimeImplementation'
| 'handleResolver'
| 'sessionStore'
| 'stateStore'
> & {
fallbackNameservers?: AtprotoHandleResolverNodeOptions['fallbackNameservers']
responseMode?: OAuthResponseMode
stateStore: NodeSavedStateStore
sessionStore: NodeSavedSessionStore
requestLock?: RuntimeLock
}
export type NodeOAuthClientFromMetadataOptions =
OAuthClientFetchMetadataOptions &
Omit<NodeOAuthClientOptions, 'clientMetadata'>
export class NodeOAuthClient extends OAuthClient {
static async fromClientId(options: NodeOAuthClientFromMetadataOptions) {
const clientMetadata = await OAuthClient.fetchMetadata(options)
return new NodeOAuthClient({ ...options, clientMetadata })
}
constructor({
fetch,
responseMode = 'query',
fallbackNameservers,
stateStore,
sessionStore,
requestLock = undefined,
...options
}: NodeOAuthClientOptions) {
if (!requestLock) {
// Ok if only one instance of the client is running at a time.
console.warn('No lock mechanism provided. Credentials might get revoked.')
}
super({
fetch,
responseMode,
handleResolver: new AtprotoHandleResolverNode({
fetch,
fallbackNameservers,
}),
runtimeImplementation: {
requestLock,
createKey: (algs) => JoseKey.generate(algs),
getRandomValues: randomBytes,
digest: (bytes, algorithm) =>
createHash(algorithm.name).update(bytes).digest(),
},
stateStore: toDpopKeyStore(stateStore),
sessionStore: toDpopKeyStore(sessionStore),
...options,
})
}
}