A social knowledge tool for researchers built on ATProto
1import {
2 NodeOAuthClient,
3 OAuthClientMetadataInput,
4 NodeSavedStateStore,
5 NodeSavedSessionStore,
6} from '@atproto/oauth-client-node';
7import { InMemoryStateStore } from '../../tests/infrastructure/InMemoryStateStore';
8import { InMemorySessionStore } from '../../tests/infrastructure/InMemorySessionStore';
9import { configService } from 'src/shared/infrastructure/config';
10
11export class OAuthClientFactory {
12 static getClientMetadata(
13 baseUrl: string,
14 appName: string = 'Semble',
15 ): { clientMetadata: OAuthClientMetadataInput } {
16 const url = baseUrl || 'http://127.0.0.1:3000';
17 const enc = encodeURIComponent;
18 const isLocal = configService.get().environment === 'local';
19
20 return {
21 clientMetadata: {
22 client_name: appName,
23 client_id: !isLocal
24 ? `${url}/atproto/client-metadata.json`
25 : `http://localhost?redirect_uri=${enc(`${baseUrl}/api/users/oauth/callback`)}&scope=${enc('atproto transition:generic')}`,
26 client_uri: url,
27 redirect_uris: [`${baseUrl}/api/users/oauth/callback`],
28 scope: 'atproto transition:generic',
29 grant_types: ['authorization_code', 'refresh_token'],
30 response_types: ['code'],
31 application_type: 'web',
32 token_endpoint_auth_method: 'none',
33 dpop_bound_access_tokens: true,
34 },
35 };
36 }
37
38 static createClient(
39 stateStore: NodeSavedStateStore,
40 sessionStore: NodeSavedSessionStore,
41 baseUrl: string,
42 appName: string = 'Semble',
43 ): NodeOAuthClient {
44 const { clientMetadata } = this.getClientMetadata(baseUrl, appName);
45
46 return new NodeOAuthClient({
47 clientMetadata,
48 stateStore,
49 sessionStore,
50 });
51 }
52
53 static createInMemoryClient(
54 baseUrl: string,
55 appName: string = 'Semble',
56 ): NodeOAuthClient {
57 const { clientMetadata } = this.getClientMetadata(baseUrl, appName);
58 const stateStore = new InMemoryStateStore();
59 const sessionStore = new InMemorySessionStore();
60
61 return new NodeOAuthClient({
62 clientMetadata,
63 stateStore,
64 sessionStore,
65 });
66 }
67}