@atcute/oauth-browser-client 1.0.25 → 2.0.0-next.0
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/LICENSE +12 -15
- package/README.md +35 -222
- package/dist/agents/exchange.d.ts +10 -5
- package/dist/agents/exchange.js +13 -1
- package/dist/agents/exchange.js.map +1 -1
- package/dist/agents/server-agent.js +3 -3
- package/dist/agents/server-agent.js.map +1 -1
- package/dist/agents/sessions.js.map +1 -1
- package/dist/agents/user-agent.js +1 -2
- package/dist/agents/user-agent.js.map +1 -1
- package/dist/dpop.d.ts +2 -2
- package/dist/dpop.js +20 -10
- package/dist/dpop.js.map +1 -1
- package/dist/environment.d.ts +9 -2
- package/dist/environment.js +3 -0
- package/dist/environment.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/resolvers.d.ts +3 -45
- package/dist/resolvers.js +36 -118
- package/dist/resolvers.js.map +1 -1
- package/lib/agents/exchange.ts +22 -7
- package/lib/agents/server-agent.ts +3 -3
- package/lib/agents/sessions.ts +5 -5
- package/lib/agents/user-agent.ts +1 -2
- package/lib/dpop.ts +30 -18
- package/lib/environment.ts +14 -2
- package/lib/index.ts +0 -1
- package/lib/resolvers.ts +42 -139
- package/package.json +6 -5
package/lib/resolvers.ts
CHANGED
|
@@ -1,92 +1,61 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import type { Did, InferXRPCBodyOutput } from '@atcute/lexicons';
|
|
1
|
+
import { getPdsEndpoint } from '@atcute/identity';
|
|
2
|
+
import type { ActorIdentifier, Did } from '@atcute/lexicons';
|
|
4
3
|
import { isDid } from '@atcute/lexicons/syntax';
|
|
5
4
|
|
|
6
|
-
import {
|
|
5
|
+
import { didDocumentResolver, handleResolver } from './environment.js';
|
|
7
6
|
import { ResolverError } from './errors.js';
|
|
8
7
|
import type { IdentityMetadata } from './types/identity.js';
|
|
9
8
|
import type { AuthorizationServerMetadata, ProtectedResourceMetadata } from './types/server.js';
|
|
10
9
|
import { extractContentType } from './utils/response.js';
|
|
11
10
|
import { isValidUrl } from './utils/strings.js';
|
|
12
11
|
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const url = DEFAULT_APPVIEW_URL + `/xrpc/com.atproto.identity.resolveHandle` + `?handle=${handle}`;
|
|
23
|
-
|
|
24
|
-
const response = await fetch(url);
|
|
25
|
-
if (response.status === 400) {
|
|
26
|
-
throw new ResolverError(`domain handle not found`);
|
|
27
|
-
} else if (!response.ok) {
|
|
28
|
-
throw new ResolverError(`directory is unreachable`);
|
|
12
|
+
export const resolveFromIdentifier = async (
|
|
13
|
+
ident: ActorIdentifier,
|
|
14
|
+
): Promise<{ identity: IdentityMetadata; metadata: AuthorizationServerMetadata }> => {
|
|
15
|
+
let did: Did;
|
|
16
|
+
if (isDid(ident)) {
|
|
17
|
+
did = ident;
|
|
18
|
+
} else {
|
|
19
|
+
const resolved = await handleResolver.resolve(ident);
|
|
20
|
+
did = resolved;
|
|
29
21
|
}
|
|
30
22
|
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
>;
|
|
34
|
-
return json.did;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Get DID documents of did:plc (via plc.directory) and did:web identifiers
|
|
39
|
-
* @param did DID identifier we're seeking DID doc from
|
|
40
|
-
* @returns Retrieved DID document
|
|
41
|
-
*/
|
|
42
|
-
export const getDidDocument = async (did: Did): Promise<DidDocument> => {
|
|
43
|
-
const colon_index = did.indexOf(':', 4);
|
|
44
|
-
|
|
45
|
-
const type = did.slice(4, colon_index);
|
|
46
|
-
const ident = did.slice(colon_index + 1);
|
|
47
|
-
|
|
48
|
-
// 2. retrieve their DID documents
|
|
49
|
-
let doc: DidDocument;
|
|
50
|
-
|
|
51
|
-
if (type === 'plc') {
|
|
52
|
-
const response = await fetch(`https://plc.directory/${did}`);
|
|
53
|
-
|
|
54
|
-
if (response.status === 404) {
|
|
55
|
-
throw new ResolverError(`did not found in directory`);
|
|
56
|
-
} else if (!response.ok) {
|
|
57
|
-
throw new ResolverError(`directory is unreachable`);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const json = await response.json();
|
|
23
|
+
const doc = await didDocumentResolver.resolve(did);
|
|
24
|
+
const pds = getPdsEndpoint(doc);
|
|
61
25
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
throw new ResolverError(`invalid identifier`);
|
|
66
|
-
}
|
|
26
|
+
if (!pds) {
|
|
27
|
+
throw new ResolverError(`missing pds endpoint`);
|
|
28
|
+
}
|
|
67
29
|
|
|
68
|
-
|
|
30
|
+
return {
|
|
31
|
+
identity: {
|
|
32
|
+
id: did,
|
|
33
|
+
raw: ident,
|
|
34
|
+
pds: new URL(pds),
|
|
35
|
+
},
|
|
36
|
+
metadata: await getMetadataFromResourceServer(pds),
|
|
37
|
+
};
|
|
38
|
+
};
|
|
69
39
|
|
|
70
|
-
|
|
71
|
-
|
|
40
|
+
export const resolveFromService = async (
|
|
41
|
+
host: string,
|
|
42
|
+
): Promise<{ metadata: AuthorizationServerMetadata }> => {
|
|
43
|
+
try {
|
|
44
|
+
const metadata = await getMetadataFromResourceServer(host);
|
|
45
|
+
return { metadata };
|
|
46
|
+
} catch (err) {
|
|
47
|
+
if (err instanceof ResolverError) {
|
|
48
|
+
try {
|
|
49
|
+
const metadata = await getAuthorizationServerMetadata(host);
|
|
50
|
+
return { metadata };
|
|
51
|
+
} catch {}
|
|
72
52
|
}
|
|
73
53
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
doc = json as DidDocument;
|
|
77
|
-
} else {
|
|
78
|
-
throw new ResolverError(`unsupported did method`);
|
|
54
|
+
throw err;
|
|
79
55
|
}
|
|
80
|
-
|
|
81
|
-
return doc;
|
|
82
56
|
};
|
|
83
57
|
|
|
84
|
-
|
|
85
|
-
* Get OAuth protected resource metadata from a host
|
|
86
|
-
* @param host URL of the host
|
|
87
|
-
* @returns Retrieved protected resource metadata
|
|
88
|
-
*/
|
|
89
|
-
export const getProtectedResourceMetadata = async (host: string): Promise<ProtectedResourceMetadata> => {
|
|
58
|
+
const getProtectedResourceMetadata = async (host: string): Promise<ProtectedResourceMetadata> => {
|
|
90
59
|
const url = new URL(`/.well-known/oauth-protected-resource`, host);
|
|
91
60
|
const response = await fetch(url, {
|
|
92
61
|
redirect: 'manual',
|
|
@@ -107,12 +76,7 @@ export const getProtectedResourceMetadata = async (host: string): Promise<Protec
|
|
|
107
76
|
return metadata;
|
|
108
77
|
};
|
|
109
78
|
|
|
110
|
-
|
|
111
|
-
* Get OAuth authorization server metadata from a host
|
|
112
|
-
* @param host URL of the host
|
|
113
|
-
* @returns Retrieved authorization server metadata
|
|
114
|
-
*/
|
|
115
|
-
export const getAuthorizationServerMetadata = async (host: string): Promise<AuthorizationServerMetadata> => {
|
|
79
|
+
const getAuthorizationServerMetadata = async (host: string): Promise<AuthorizationServerMetadata> => {
|
|
116
80
|
const url = new URL(`/.well-known/oauth-authorization-server`, host);
|
|
117
81
|
const response = await fetch(url, {
|
|
118
82
|
redirect: 'manual',
|
|
@@ -147,68 +111,7 @@ export const getAuthorizationServerMetadata = async (host: string): Promise<Auth
|
|
|
147
111
|
return metadata;
|
|
148
112
|
};
|
|
149
113
|
|
|
150
|
-
|
|
151
|
-
* Resolve handle domains or DID identifiers to get their PDS and its authorization server metadata
|
|
152
|
-
* @param ident Handle domain or DID identifier to resolve
|
|
153
|
-
* @returns Resolved PDS and authorization server metadata
|
|
154
|
-
*/
|
|
155
|
-
export const resolveFromIdentity = async (
|
|
156
|
-
ident: string,
|
|
157
|
-
): Promise<{ identity: IdentityMetadata; metadata: AuthorizationServerMetadata }> => {
|
|
158
|
-
let did: Did;
|
|
159
|
-
if (isDid(ident)) {
|
|
160
|
-
did = ident;
|
|
161
|
-
} else {
|
|
162
|
-
const resolved = await resolveHandle(ident);
|
|
163
|
-
did = resolved;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const doc = await getDidDocument(did);
|
|
167
|
-
const pds = getPdsEndpoint(doc);
|
|
168
|
-
|
|
169
|
-
if (!pds) {
|
|
170
|
-
throw new ResolverError(`missing pds endpoint`);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return {
|
|
174
|
-
identity: {
|
|
175
|
-
id: did,
|
|
176
|
-
raw: ident,
|
|
177
|
-
pds: new URL(pds),
|
|
178
|
-
},
|
|
179
|
-
metadata: await getMetadataFromResourceServer(pds),
|
|
180
|
-
};
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Request authorization server metadata from a PDS
|
|
185
|
-
* @param host URL of the host
|
|
186
|
-
* @returns Resolved authorization server metadata
|
|
187
|
-
*/
|
|
188
|
-
export const resolveFromService = async (
|
|
189
|
-
host: string,
|
|
190
|
-
): Promise<{ metadata: AuthorizationServerMetadata }> => {
|
|
191
|
-
try {
|
|
192
|
-
const metadata = await getMetadataFromResourceServer(host);
|
|
193
|
-
return { metadata };
|
|
194
|
-
} catch (err) {
|
|
195
|
-
if (err instanceof ResolverError) {
|
|
196
|
-
try {
|
|
197
|
-
const metadata = await getAuthorizationServerMetadata(host);
|
|
198
|
-
return { metadata };
|
|
199
|
-
} catch {}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
throw err;
|
|
203
|
-
}
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Request authorization server metadata from its protected resource metadata
|
|
208
|
-
* @param input URL of the host whose authorization server is delegated
|
|
209
|
-
* @returns Resolved authorization server metadata
|
|
210
|
-
*/
|
|
211
|
-
export const getMetadataFromResourceServer = async (input: string) => {
|
|
114
|
+
const getMetadataFromResourceServer = async (input: string) => {
|
|
212
115
|
const rs_metadata = await getProtectedResourceMetadata(input);
|
|
213
116
|
|
|
214
117
|
if (rs_metadata.authorization_servers?.length !== 1) {
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@atcute/oauth-browser-client",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.0-next.0",
|
|
5
5
|
"description": "minimal OAuth browser client implementation for AT Protocol",
|
|
6
|
-
"license": "
|
|
6
|
+
"license": "0BSD",
|
|
7
7
|
"repository": {
|
|
8
8
|
"url": "https://github.com/mary-ext/atcute",
|
|
9
9
|
"directory": "packages/oauth/browser-client"
|
|
@@ -20,14 +20,15 @@
|
|
|
20
20
|
"sideEffects": false,
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"nanoid": "^5.1.5",
|
|
23
|
-
"@atcute/identity": "^1.0
|
|
24
|
-
"@atcute/
|
|
23
|
+
"@atcute/identity": "^1.1.0",
|
|
24
|
+
"@atcute/identity-resolver": "^1.1.3",
|
|
25
25
|
"@atcute/client": "^4.0.3",
|
|
26
|
+
"@atcute/lexicons": "^1.1.1",
|
|
26
27
|
"@atcute/multibase": "^1.1.4",
|
|
27
28
|
"@atcute/uint8array": "^1.0.3"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
30
|
-
"@atcute/atproto": "^3.
|
|
31
|
+
"@atcute/atproto": "^3.1.2"
|
|
31
32
|
},
|
|
32
33
|
"scripts": {
|
|
33
34
|
"build": "tsc --project tsconfig.build.json",
|