tangled
alpha
login
or
join now
modamo.xyz
/
bambu
1
fork
atom
this repo has no description
1
fork
atom
overview
issues
pulls
pipelines
Begin OAuth flow
modamo-gh
1 month ago
519cc172
f127d455
+528
-4
6 changed files
expand all
collapse all
unified
split
app
oauth
callback
route.ts
login
route.ts
components
LoginForm.tsx
lib
auth
client.ts
package-lock.json
package.json
+18
app/oauth/callback/route.ts
···
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
···
1
+
import { getOAuthClient } from "@/lib/auth/client";
2
+
import { NextRequest, NextResponse } from "next/server";
3
+
4
+
const PUBLIC_URL = process.env.PUBLIC_URL || "http://127.0.0.1:3000";
5
+
6
+
export async function GET(request: NextRequest) {
7
+
try {
8
+
const params = request.nextUrl.searchParams;
9
+
const client = await getOAuthClient();
10
+
const {session} = await client.
11
+
} catch (error) {
12
+
console.error("OAuth callback error:", error);
13
+
14
+
return NextResponse.redirect(
15
+
new URL("/?error=login_failed", PUBLIC_URL)
16
+
);
17
+
}
18
+
}
+29
app/oauth/login/route.ts
···
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
···
1
+
import { getOAuthClient, SCOPE } from "@/lib/auth/client";
2
+
import { NextRequest, NextResponse } from "next/server";
3
+
4
+
export async function POST(request: NextRequest) {
5
+
try {
6
+
const { handle } = await request.json();
7
+
8
+
if (!handle || typeof handle !== "string") {
9
+
return NextResponse.json(
10
+
{ error: "Handle is required" },
11
+
{ status: 400 }
12
+
);
13
+
}
14
+
15
+
const client = await getOAuthClient();
16
+
const authURL = await client?.authorize(handle, { scope: SCOPE });
17
+
18
+
return NextResponse.json({ redirectURL: authURL?.toString() });
19
+
} catch (error) {
20
+
console.error("OAuth login error:", error);
21
+
22
+
return NextResponse.json(
23
+
{
24
+
error: error instanceof Error ? error.message : "Login failed"
25
+
},
26
+
{ status: 500 }
27
+
);
28
+
}
29
+
}
+35
-4
components/LoginForm.tsx
···
4
5
const LoginForm = () => {
6
const [handle, setHandle] = useState("");
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
7
8
return (
9
-
<form className="bg-amber-100 flex flex-col h-fit items-center justify-center p-4 rounded-2xl w-1/3">
0
0
0
10
<div className="flex flex-col p-4 rounded-2xl w-full">
11
<label
12
className="text-emerald-900"
···
16
</label>
17
<input
18
className="bg-emerald-900 px-4 py-2 rounded-lg"
19
-
id="handle"
20
onChange={(event) => setHandle(event.currentTarget.value)}
21
placeholder="alice.blacksky.app"
22
type="text"
23
value={handle}
24
/>
25
</div>
26
-
<button className="bg-emerald-900 px-4 py-2 rounded-lg">
27
-
Log into the Atmosphere
0
0
0
28
</button>
29
</form>
30
);
···
4
5
const LoginForm = () => {
6
const [handle, setHandle] = useState("");
7
+
const [isLoading, setIsLoading] = useState(false);
8
+
9
+
const handleSubmit = async (event: Event) => {
10
+
event.preventDefault();
11
+
12
+
setIsLoading(true);
13
+
14
+
try {
15
+
const response = await fetch("/oauth/login", {
16
+
body: JSON.stringify({ handle }),
17
+
headers: { "Content-Type": "application/json" },
18
+
method: "POST"
19
+
});
20
+
const json = await response.json();
21
+
22
+
if(!response.ok){
23
+
throw new Error(json.error || "Login failed")
24
+
}
25
+
26
+
window.location.href = json.redirectURL;
27
+
} catch (error) {
28
+
} finally {
29
+
setIsLoading(false);
30
+
}
31
+
};
32
33
return (
34
+
<form
35
+
className="bg-amber-100 flex flex-col h-fit items-center justify-center p-4 rounded-2xl w-1/3"
36
+
onSubmit={handleSubmit}
37
+
>
38
<div className="flex flex-col p-4 rounded-2xl w-full">
39
<label
40
className="text-emerald-900"
···
44
</label>
45
<input
46
className="bg-emerald-900 px-4 py-2 rounded-lg"
47
+
id="handle"
48
onChange={(event) => setHandle(event.currentTarget.value)}
49
placeholder="alice.blacksky.app"
50
type="text"
51
value={handle}
52
/>
53
</div>
54
+
<button
55
+
className="hover:bg-emerald-800 bg-emerald-900 cursor-pointer px-4 py-2 rounded-lg"
56
+
disabled={!handle || isLoading}
57
+
>
58
+
{isLoading ? "Logging in ..." : "Log into the Atmosphere"}
59
</button>
60
</form>
61
);
+29
lib/auth/client.ts
···
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
···
1
+
import {
2
+
buildAtprotoLoopbackClientMetadata,
3
+
NodeOAuthClient
4
+
} from "@atproto/oauth-client-node";
5
+
6
+
const PUBLIC_URL = process.env.PUBLIC_URL;
7
+
8
+
export const SCOPE = "atproto";
9
+
10
+
let client: NodeOAuthClient | null = null;
11
+
12
+
const getClientMetadata = () => {
13
+
if (PUBLIC_URL) {
14
+
} else {
15
+
return buildAtprotoLoopbackClientMetadata({
16
+
redirect_uris: ["http://127.0.0.1:3000/oauth/callback"],
17
+
scope: SCOPE
18
+
});
19
+
}
20
+
};
21
+
export const getOAuthClient = async () => {
22
+
if (client) {
23
+
return client;
24
+
}
25
+
26
+
client = new NodeOAuthClient({
27
+
clientMetadata: getClientMetadata()
28
+
});
29
+
};
+416
package-lock.json
···
8
"name": "bambu",
9
"version": "0.1.0",
10
"dependencies": {
0
11
"next": "16.1.6",
12
"react": "19.2.3",
13
"react-dom": "19.2.3"
···
36
"url": "https://github.com/sponsors/sindresorhus"
37
}
38
},
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
39
"node_modules/@babel/code-frame": {
40
"version": "7.29.0",
41
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
···
2610
"dev": true,
2611
"license": "MIT"
2612
},
0
0
0
0
0
0
0
0
0
0
0
2613
"node_modules/cross-spawn": {
2614
"version": "7.0.6",
2615
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
···
3942
"node": ">= 0.4"
3943
}
3944
},
0
0
0
0
0
0
0
0
0
3945
"node_modules/is-array-buffer": {
3946
"version": "3.0.5",
3947
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
···
4371
"dev": true,
4372
"license": "ISC"
4373
},
0
0
0
0
0
0
4374
"node_modules/iterator.prototype": {
4375
"version": "1.1.5",
4376
"resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz",
···
4397
"license": "MIT",
4398
"bin": {
4399
"jiti": "lib/jiti-cli.mjs"
0
0
0
0
0
0
0
0
0
4400
}
4401
},
4402
"node_modules/js-tokens": {
···
4906
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
4907
"dev": true,
4908
"license": "MIT"
0
0
0
0
0
0
4909
},
4910
"node_modules/nanoid": {
4911
"version": "3.3.11",
···
6274
"typescript": ">=4.8.4 <6.0.0"
6275
}
6276
},
0
0
0
0
0
0
0
0
0
6277
"node_modules/unbox-primitive": {
6278
"version": "1.1.0",
6279
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
···
6293
"url": "https://github.com/sponsors/ljharb"
6294
}
6295
},
0
0
0
0
0
0
0
0
0
6296
"node_modules/undici-types": {
6297
"version": "6.21.0",
6298
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
6299
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
6300
"dev": true,
0
0
0
0
0
0
6301
"license": "MIT"
6302
},
6303
"node_modules/unrs-resolver": {
···
8
"name": "bambu",
9
"version": "0.1.0",
10
"dependencies": {
11
+
"@atproto/oauth-client-node": "^0.3.16",
12
"next": "16.1.6",
13
"react": "19.2.3",
14
"react-dom": "19.2.3"
···
37
"url": "https://github.com/sponsors/sindresorhus"
38
}
39
},
40
+
"node_modules/@atproto-labs/did-resolver": {
41
+
"version": "0.2.6",
42
+
"resolved": "https://registry.npmjs.org/@atproto-labs/did-resolver/-/did-resolver-0.2.6.tgz",
43
+
"integrity": "sha512-2K1bC04nI2fmgNcvof+yA28IhGlpWn2JKYlPa7To9JTKI45FINCGkQSGiL2nyXlyzDJJ34fZ1aq6/IRFIOIiqg==",
44
+
"license": "MIT",
45
+
"dependencies": {
46
+
"@atproto-labs/fetch": "0.2.3",
47
+
"@atproto-labs/pipe": "0.1.1",
48
+
"@atproto-labs/simple-store": "0.3.0",
49
+
"@atproto-labs/simple-store-memory": "0.1.4",
50
+
"@atproto/did": "0.3.0",
51
+
"zod": "^3.23.8"
52
+
}
53
+
},
54
+
"node_modules/@atproto-labs/did-resolver/node_modules/zod": {
55
+
"version": "3.25.76",
56
+
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
57
+
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
58
+
"license": "MIT",
59
+
"funding": {
60
+
"url": "https://github.com/sponsors/colinhacks"
61
+
}
62
+
},
63
+
"node_modules/@atproto-labs/fetch": {
64
+
"version": "0.2.3",
65
+
"resolved": "https://registry.npmjs.org/@atproto-labs/fetch/-/fetch-0.2.3.tgz",
66
+
"integrity": "sha512-NZtbJOCbxKUFRFKMpamT38PUQMY0hX0p7TG5AEYOPhZKZEP7dHZ1K2s1aB8MdVH0qxmqX7nQleNrrvLf09Zfdw==",
67
+
"license": "MIT",
68
+
"dependencies": {
69
+
"@atproto-labs/pipe": "0.1.1"
70
+
}
71
+
},
72
+
"node_modules/@atproto-labs/fetch-node": {
73
+
"version": "0.2.0",
74
+
"resolved": "https://registry.npmjs.org/@atproto-labs/fetch-node/-/fetch-node-0.2.0.tgz",
75
+
"integrity": "sha512-Krq09nH/aeoiU2s9xdHA0FjTEFWG9B5FFenipv1iRixCcPc7V3DhTNDawxG9gI8Ny0k4dBVS9WTRN/IDzBx86Q==",
76
+
"license": "MIT",
77
+
"dependencies": {
78
+
"@atproto-labs/fetch": "0.2.3",
79
+
"@atproto-labs/pipe": "0.1.1",
80
+
"ipaddr.js": "^2.1.0",
81
+
"undici": "^6.14.1"
82
+
},
83
+
"engines": {
84
+
"node": ">=18.7.0"
85
+
}
86
+
},
87
+
"node_modules/@atproto-labs/handle-resolver": {
88
+
"version": "0.3.6",
89
+
"resolved": "https://registry.npmjs.org/@atproto-labs/handle-resolver/-/handle-resolver-0.3.6.tgz",
90
+
"integrity": "sha512-qnSTXvOBNj1EHhp2qTWSX8MS5q3AwYU5LKlt5fBvSbCjgmTr2j0URHCv+ydrwO55KvsojIkTMgeMOh4YuY4fCA==",
91
+
"license": "MIT",
92
+
"dependencies": {
93
+
"@atproto-labs/simple-store": "0.3.0",
94
+
"@atproto-labs/simple-store-memory": "0.1.4",
95
+
"@atproto/did": "0.3.0",
96
+
"zod": "^3.23.8"
97
+
}
98
+
},
99
+
"node_modules/@atproto-labs/handle-resolver-node": {
100
+
"version": "0.1.25",
101
+
"resolved": "https://registry.npmjs.org/@atproto-labs/handle-resolver-node/-/handle-resolver-node-0.1.25.tgz",
102
+
"integrity": "sha512-NY9WYM2VLd3IuMGRkkmvGBg8xqVEaK/fitv1vD8SMXqFTekdpjOLCCyv7EFtqVHouzmDcL83VOvWRfHVa8V9Yw==",
103
+
"license": "MIT",
104
+
"dependencies": {
105
+
"@atproto-labs/fetch-node": "0.2.0",
106
+
"@atproto-labs/handle-resolver": "0.3.6",
107
+
"@atproto/did": "0.3.0"
108
+
},
109
+
"engines": {
110
+
"node": ">=18.7.0"
111
+
}
112
+
},
113
+
"node_modules/@atproto-labs/handle-resolver/node_modules/zod": {
114
+
"version": "3.25.76",
115
+
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
116
+
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
117
+
"license": "MIT",
118
+
"funding": {
119
+
"url": "https://github.com/sponsors/colinhacks"
120
+
}
121
+
},
122
+
"node_modules/@atproto-labs/identity-resolver": {
123
+
"version": "0.3.6",
124
+
"resolved": "https://registry.npmjs.org/@atproto-labs/identity-resolver/-/identity-resolver-0.3.6.tgz",
125
+
"integrity": "sha512-qoWqBDRobln0NR8L8dQjSp79E0chGkBhibEgxQa2f9WD+JbJdjQ0YvwwO5yeQn05pJoJmAwmI2wyJ45zjU7aWg==",
126
+
"license": "MIT",
127
+
"dependencies": {
128
+
"@atproto-labs/did-resolver": "0.2.6",
129
+
"@atproto-labs/handle-resolver": "0.3.6"
130
+
}
131
+
},
132
+
"node_modules/@atproto-labs/pipe": {
133
+
"version": "0.1.1",
134
+
"resolved": "https://registry.npmjs.org/@atproto-labs/pipe/-/pipe-0.1.1.tgz",
135
+
"integrity": "sha512-hdNw2oUs2B6BN1lp+32pF7cp8EMKuIN5Qok2Vvv/aOpG/3tNSJ9YkvfI0k6Zd188LeDDYRUpYpxcoFIcGH/FNg==",
136
+
"license": "MIT"
137
+
},
138
+
"node_modules/@atproto-labs/simple-store": {
139
+
"version": "0.3.0",
140
+
"resolved": "https://registry.npmjs.org/@atproto-labs/simple-store/-/simple-store-0.3.0.tgz",
141
+
"integrity": "sha512-nOb6ONKBRJHRlukW1sVawUkBqReLlLx6hT35VS3imaNPwiXDxLnTK7lxw3Lrl9k5yugSBDQAkZAq3MPTEFSUBQ==",
142
+
"license": "MIT"
143
+
},
144
+
"node_modules/@atproto-labs/simple-store-memory": {
145
+
"version": "0.1.4",
146
+
"resolved": "https://registry.npmjs.org/@atproto-labs/simple-store-memory/-/simple-store-memory-0.1.4.tgz",
147
+
"integrity": "sha512-3mKY4dP8I7yKPFj9VKpYyCRzGJOi5CEpOLPlRhoJyLmgs3J4RzDrjn323Oakjz2Aj2JzRU/AIvWRAZVhpYNJHw==",
148
+
"license": "MIT",
149
+
"dependencies": {
150
+
"@atproto-labs/simple-store": "0.3.0",
151
+
"lru-cache": "^10.2.0"
152
+
}
153
+
},
154
+
"node_modules/@atproto-labs/simple-store-memory/node_modules/lru-cache": {
155
+
"version": "10.4.3",
156
+
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
157
+
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
158
+
"license": "ISC"
159
+
},
160
+
"node_modules/@atproto/common-web": {
161
+
"version": "0.4.15",
162
+
"resolved": "https://registry.npmjs.org/@atproto/common-web/-/common-web-0.4.15.tgz",
163
+
"integrity": "sha512-A4l9gyqUNez8CjZp/Trypz/D3WIQsNj8dN05WR6+RoBbvwc9JhWjKPrm+WoVYc/F16RPdXHLkE3BEJlGIyYIiA==",
164
+
"license": "MIT",
165
+
"dependencies": {
166
+
"@atproto/lex-data": "^0.0.10",
167
+
"@atproto/lex-json": "^0.0.10",
168
+
"@atproto/syntax": "^0.4.3",
169
+
"zod": "^3.23.8"
170
+
}
171
+
},
172
+
"node_modules/@atproto/common-web/node_modules/zod": {
173
+
"version": "3.25.76",
174
+
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
175
+
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
176
+
"license": "MIT",
177
+
"funding": {
178
+
"url": "https://github.com/sponsors/colinhacks"
179
+
}
180
+
},
181
+
"node_modules/@atproto/did": {
182
+
"version": "0.3.0",
183
+
"resolved": "https://registry.npmjs.org/@atproto/did/-/did-0.3.0.tgz",
184
+
"integrity": "sha512-raUPzUGegtW/6OxwCmM8bhZvuIMzxG5t9oWsth6Tp91Kb5fTnHV2h/KKNF1C82doeA4BdXCErTyg7ISwLbQkzA==",
185
+
"license": "MIT",
186
+
"dependencies": {
187
+
"zod": "^3.23.8"
188
+
}
189
+
},
190
+
"node_modules/@atproto/did/node_modules/zod": {
191
+
"version": "3.25.76",
192
+
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
193
+
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
194
+
"license": "MIT",
195
+
"funding": {
196
+
"url": "https://github.com/sponsors/colinhacks"
197
+
}
198
+
},
199
+
"node_modules/@atproto/jwk": {
200
+
"version": "0.6.0",
201
+
"resolved": "https://registry.npmjs.org/@atproto/jwk/-/jwk-0.6.0.tgz",
202
+
"integrity": "sha512-bDoJPvt7TrQVi/rBfBrSSpGykhtIriKxeYCYQTiPRKFfyRhbgpElF0wPXADjIswnbzZdOwbY63az4E/CFVT3Tw==",
203
+
"license": "MIT",
204
+
"dependencies": {
205
+
"multiformats": "^9.9.0",
206
+
"zod": "^3.23.8"
207
+
}
208
+
},
209
+
"node_modules/@atproto/jwk-jose": {
210
+
"version": "0.1.11",
211
+
"resolved": "https://registry.npmjs.org/@atproto/jwk-jose/-/jwk-jose-0.1.11.tgz",
212
+
"integrity": "sha512-i4Fnr2sTBYmMmHXl7NJh8GrCH+tDQEVWrcDMDnV5DjJfkgT17wIqvojIw9SNbSL4Uf0OtfEv6AgG0A+mgh8b5Q==",
213
+
"license": "MIT",
214
+
"dependencies": {
215
+
"@atproto/jwk": "0.6.0",
216
+
"jose": "^5.2.0"
217
+
}
218
+
},
219
+
"node_modules/@atproto/jwk-webcrypto": {
220
+
"version": "0.2.0",
221
+
"resolved": "https://registry.npmjs.org/@atproto/jwk-webcrypto/-/jwk-webcrypto-0.2.0.tgz",
222
+
"integrity": "sha512-UmgRrrEAkWvxwhlwe30UmDOdTEFidlIzBC7C3cCbeJMcBN1x8B3KH+crXrsTqfWQBG58mXgt8wgSK3Kxs2LhFg==",
223
+
"license": "MIT",
224
+
"dependencies": {
225
+
"@atproto/jwk": "0.6.0",
226
+
"@atproto/jwk-jose": "0.1.11",
227
+
"zod": "^3.23.8"
228
+
}
229
+
},
230
+
"node_modules/@atproto/jwk-webcrypto/node_modules/zod": {
231
+
"version": "3.25.76",
232
+
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
233
+
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
234
+
"license": "MIT",
235
+
"funding": {
236
+
"url": "https://github.com/sponsors/colinhacks"
237
+
}
238
+
},
239
+
"node_modules/@atproto/jwk/node_modules/zod": {
240
+
"version": "3.25.76",
241
+
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
242
+
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
243
+
"license": "MIT",
244
+
"funding": {
245
+
"url": "https://github.com/sponsors/colinhacks"
246
+
}
247
+
},
248
+
"node_modules/@atproto/lex-data": {
249
+
"version": "0.0.10",
250
+
"resolved": "https://registry.npmjs.org/@atproto/lex-data/-/lex-data-0.0.10.tgz",
251
+
"integrity": "sha512-FDbcy8VIUVzS9Mi1F8SMxbkL/jOUmRRpqbeM1xB4A0fMxeZJTxf6naAbFt4gYF3quu/+TPJGmio6/7cav05FqQ==",
252
+
"license": "MIT",
253
+
"dependencies": {
254
+
"multiformats": "^9.9.0",
255
+
"tslib": "^2.8.1",
256
+
"uint8arrays": "3.0.0",
257
+
"unicode-segmenter": "^0.14.0"
258
+
}
259
+
},
260
+
"node_modules/@atproto/lex-json": {
261
+
"version": "0.0.10",
262
+
"resolved": "https://registry.npmjs.org/@atproto/lex-json/-/lex-json-0.0.10.tgz",
263
+
"integrity": "sha512-L6MyXU17C5ODMeob8myQ2F3xvgCTvJUtM0ew8qSApnN//iDasB/FDGgd7ty4UVNmx4NQ/rtvz8xV94YpG6kneQ==",
264
+
"license": "MIT",
265
+
"dependencies": {
266
+
"@atproto/lex-data": "^0.0.10",
267
+
"tslib": "^2.8.1"
268
+
}
269
+
},
270
+
"node_modules/@atproto/lexicon": {
271
+
"version": "0.6.1",
272
+
"resolved": "https://registry.npmjs.org/@atproto/lexicon/-/lexicon-0.6.1.tgz",
273
+
"integrity": "sha512-/vI1kVlY50Si+5MXpvOucelnYwb0UJ6Qto5mCp+7Q5C+Jtp+SoSykAPVvjVtTnQUH2vrKOFOwpb3C375vSKzXw==",
274
+
"license": "MIT",
275
+
"dependencies": {
276
+
"@atproto/common-web": "^0.4.13",
277
+
"@atproto/syntax": "^0.4.3",
278
+
"iso-datestring-validator": "^2.2.2",
279
+
"multiformats": "^9.9.0",
280
+
"zod": "^3.23.8"
281
+
}
282
+
},
283
+
"node_modules/@atproto/lexicon/node_modules/zod": {
284
+
"version": "3.25.76",
285
+
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
286
+
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
287
+
"license": "MIT",
288
+
"funding": {
289
+
"url": "https://github.com/sponsors/colinhacks"
290
+
}
291
+
},
292
+
"node_modules/@atproto/oauth-client": {
293
+
"version": "0.5.14",
294
+
"resolved": "https://registry.npmjs.org/@atproto/oauth-client/-/oauth-client-0.5.14.tgz",
295
+
"integrity": "sha512-sPH+vcdq9maTEAhJI0HzmFcFAMrkCS19np+RUssNkX6kS8Xr3OYr57tvYRCbkcnIyYTfYcxKQgpwHKx3RVEaYw==",
296
+
"license": "MIT",
297
+
"dependencies": {
298
+
"@atproto-labs/did-resolver": "0.2.6",
299
+
"@atproto-labs/fetch": "0.2.3",
300
+
"@atproto-labs/handle-resolver": "0.3.6",
301
+
"@atproto-labs/identity-resolver": "0.3.6",
302
+
"@atproto-labs/simple-store": "0.3.0",
303
+
"@atproto-labs/simple-store-memory": "0.1.4",
304
+
"@atproto/did": "0.3.0",
305
+
"@atproto/jwk": "0.6.0",
306
+
"@atproto/oauth-types": "0.6.2",
307
+
"@atproto/xrpc": "0.7.7",
308
+
"core-js": "^3",
309
+
"multiformats": "^9.9.0",
310
+
"zod": "^3.23.8"
311
+
}
312
+
},
313
+
"node_modules/@atproto/oauth-client-node": {
314
+
"version": "0.3.16",
315
+
"resolved": "https://registry.npmjs.org/@atproto/oauth-client-node/-/oauth-client-node-0.3.16.tgz",
316
+
"integrity": "sha512-2dooMzxAkiQ4MkOAZlEQ3iwbB9SEovrbIKMNuBbVCLQYORVNxe20tMdjs3lvhrzdpzvaHLlQnJJhw5dA9VELFw==",
317
+
"license": "MIT",
318
+
"dependencies": {
319
+
"@atproto-labs/did-resolver": "0.2.6",
320
+
"@atproto-labs/handle-resolver-node": "0.1.25",
321
+
"@atproto-labs/simple-store": "0.3.0",
322
+
"@atproto/did": "0.3.0",
323
+
"@atproto/jwk": "0.6.0",
324
+
"@atproto/jwk-jose": "0.1.11",
325
+
"@atproto/jwk-webcrypto": "0.2.0",
326
+
"@atproto/oauth-client": "0.5.14",
327
+
"@atproto/oauth-types": "0.6.2"
328
+
},
329
+
"engines": {
330
+
"node": ">=18.7.0"
331
+
}
332
+
},
333
+
"node_modules/@atproto/oauth-client/node_modules/zod": {
334
+
"version": "3.25.76",
335
+
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
336
+
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
337
+
"license": "MIT",
338
+
"funding": {
339
+
"url": "https://github.com/sponsors/colinhacks"
340
+
}
341
+
},
342
+
"node_modules/@atproto/oauth-types": {
343
+
"version": "0.6.2",
344
+
"resolved": "https://registry.npmjs.org/@atproto/oauth-types/-/oauth-types-0.6.2.tgz",
345
+
"integrity": "sha512-2cuboM4RQBCYR8NQC5uGRkW6KgCgKyq/B5/+tnMmWZYtZGVUQvsUWQHK/ZiMCnVXbcDNtc/RIEJQJDZ8FXMoxg==",
346
+
"license": "MIT",
347
+
"dependencies": {
348
+
"@atproto/did": "0.3.0",
349
+
"@atproto/jwk": "0.6.0",
350
+
"zod": "^3.23.8"
351
+
}
352
+
},
353
+
"node_modules/@atproto/oauth-types/node_modules/zod": {
354
+
"version": "3.25.76",
355
+
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
356
+
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
357
+
"license": "MIT",
358
+
"funding": {
359
+
"url": "https://github.com/sponsors/colinhacks"
360
+
}
361
+
},
362
+
"node_modules/@atproto/syntax": {
363
+
"version": "0.4.3",
364
+
"resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.4.3.tgz",
365
+
"integrity": "sha512-YoZUz40YAJr5nPwvCDWgodEOlt5IftZqPJvA0JDWjuZKD8yXddTwSzXSaKQAzGOpuM+/A3uXRtPzJJqlScc+iA==",
366
+
"license": "MIT",
367
+
"dependencies": {
368
+
"tslib": "^2.8.1"
369
+
}
370
+
},
371
+
"node_modules/@atproto/xrpc": {
372
+
"version": "0.7.7",
373
+
"resolved": "https://registry.npmjs.org/@atproto/xrpc/-/xrpc-0.7.7.tgz",
374
+
"integrity": "sha512-K1ZyO/BU8JNtXX5dmPp7b5UrkLMMqpsIa/Lrj5D3Su+j1Xwq1m6QJ2XJ1AgjEjkI1v4Muzm7klianLE6XGxtmA==",
375
+
"license": "MIT",
376
+
"dependencies": {
377
+
"@atproto/lexicon": "^0.6.0",
378
+
"zod": "^3.23.8"
379
+
}
380
+
},
381
+
"node_modules/@atproto/xrpc/node_modules/zod": {
382
+
"version": "3.25.76",
383
+
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
384
+
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
385
+
"license": "MIT",
386
+
"funding": {
387
+
"url": "https://github.com/sponsors/colinhacks"
388
+
}
389
+
},
390
"node_modules/@babel/code-frame": {
391
"version": "7.29.0",
392
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
···
2961
"dev": true,
2962
"license": "MIT"
2963
},
2964
+
"node_modules/core-js": {
2965
+
"version": "3.48.0",
2966
+
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.48.0.tgz",
2967
+
"integrity": "sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ==",
2968
+
"hasInstallScript": true,
2969
+
"license": "MIT",
2970
+
"funding": {
2971
+
"type": "opencollective",
2972
+
"url": "https://opencollective.com/core-js"
2973
+
}
2974
+
},
2975
"node_modules/cross-spawn": {
2976
"version": "7.0.6",
2977
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
···
4304
"node": ">= 0.4"
4305
}
4306
},
4307
+
"node_modules/ipaddr.js": {
4308
+
"version": "2.3.0",
4309
+
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz",
4310
+
"integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==",
4311
+
"license": "MIT",
4312
+
"engines": {
4313
+
"node": ">= 10"
4314
+
}
4315
+
},
4316
"node_modules/is-array-buffer": {
4317
"version": "3.0.5",
4318
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
···
4742
"dev": true,
4743
"license": "ISC"
4744
},
4745
+
"node_modules/iso-datestring-validator": {
4746
+
"version": "2.2.2",
4747
+
"resolved": "https://registry.npmjs.org/iso-datestring-validator/-/iso-datestring-validator-2.2.2.tgz",
4748
+
"integrity": "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==",
4749
+
"license": "MIT"
4750
+
},
4751
"node_modules/iterator.prototype": {
4752
"version": "1.1.5",
4753
"resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz",
···
4774
"license": "MIT",
4775
"bin": {
4776
"jiti": "lib/jiti-cli.mjs"
4777
+
}
4778
+
},
4779
+
"node_modules/jose": {
4780
+
"version": "5.10.0",
4781
+
"resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz",
4782
+
"integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==",
4783
+
"license": "MIT",
4784
+
"funding": {
4785
+
"url": "https://github.com/sponsors/panva"
4786
}
4787
},
4788
"node_modules/js-tokens": {
···
5292
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
5293
"dev": true,
5294
"license": "MIT"
5295
+
},
5296
+
"node_modules/multiformats": {
5297
+
"version": "9.9.0",
5298
+
"resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz",
5299
+
"integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==",
5300
+
"license": "(Apache-2.0 AND MIT)"
5301
},
5302
"node_modules/nanoid": {
5303
"version": "3.3.11",
···
6666
"typescript": ">=4.8.4 <6.0.0"
6667
}
6668
},
6669
+
"node_modules/uint8arrays": {
6670
+
"version": "3.0.0",
6671
+
"resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.0.0.tgz",
6672
+
"integrity": "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==",
6673
+
"license": "MIT",
6674
+
"dependencies": {
6675
+
"multiformats": "^9.4.2"
6676
+
}
6677
+
},
6678
"node_modules/unbox-primitive": {
6679
"version": "1.1.0",
6680
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
···
6694
"url": "https://github.com/sponsors/ljharb"
6695
}
6696
},
6697
+
"node_modules/undici": {
6698
+
"version": "6.23.0",
6699
+
"resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz",
6700
+
"integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==",
6701
+
"license": "MIT",
6702
+
"engines": {
6703
+
"node": ">=18.17"
6704
+
}
6705
+
},
6706
"node_modules/undici-types": {
6707
"version": "6.21.0",
6708
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
6709
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
6710
"dev": true,
6711
+
"license": "MIT"
6712
+
},
6713
+
"node_modules/unicode-segmenter": {
6714
+
"version": "0.14.5",
6715
+
"resolved": "https://registry.npmjs.org/unicode-segmenter/-/unicode-segmenter-0.14.5.tgz",
6716
+
"integrity": "sha512-jHGmj2LUuqDcX3hqY12Ql+uhUTn8huuxNZGq7GvtF6bSybzH3aFgedYu/KTzQStEgt1Ra2F3HxadNXsNjb3m3g==",
6717
"license": "MIT"
6718
},
6719
"node_modules/unrs-resolver": {
+1
package.json
···
9
"lint": "eslint"
10
},
11
"dependencies": {
0
12
"next": "16.1.6",
13
"react": "19.2.3",
14
"react-dom": "19.2.3"
···
9
"lint": "eslint"
10
},
11
"dependencies": {
12
+
"@atproto/oauth-client-node": "^0.3.16",
13
"next": "16.1.6",
14
"react": "19.2.3",
15
"react-dom": "19.2.3"