+23
app/api/auth/atproto/route.ts
+23
app/api/auth/atproto/route.ts
···
1
+
import AtpAgent from "@atproto/api";
2
+
import { NextRequest, NextResponse } from "next/server";
3
+
4
+
export async function POST(request: NextRequest) {
5
+
try {
6
+
const { hostingProvider, identifier, password } = await request.json();
7
+
const hostingProviderURL = hostingProvider || "https://bsky.social";
8
+
const agent = new AtpAgent({ service: hostingProviderURL });
9
+
10
+
await agent.login({ identifier, password });
11
+
12
+
return NextResponse.json({
13
+
did: agent.session?.did,
14
+
handle: agent.session?.handle,
15
+
success: true
16
+
});
17
+
} catch (error) {
18
+
return NextResponse.json(
19
+
{ error: error.message, success: false },
20
+
{ status: 401 }
21
+
);
22
+
}
23
+
}
+26
-3
app/page.tsx
+26
-3
app/page.tsx
···
8
8
const [atProtoIdentifier, setAtProtoIdentifier] = useState("");
9
9
const [currentPlaying, setCurrentPlaying] = useState("");
10
10
const [hostingProvider, setHostingProvider] = useState("");
11
+
const [isLoggingIn, setIsLoggingIn] = useState(false);
11
12
const [lastFMUsername, setLastFMUsername] = useState("");
12
13
const [password, setPassword] = useState("");
13
14
const [usernameInput, setUsernameInput] = useState("");
14
15
16
+
const loginToATProto = async () => {
17
+
setIsLoggingIn(true);
18
+
19
+
try {
20
+
const response = await fetch("/api/auth/atproto", {
21
+
body: JSON.stringify({
22
+
hostingProvide: hostingProvider || "https://bsky.social",
23
+
identifier: atProtoIdentifier,
24
+
password
25
+
}),
26
+
headers: { "Content-Type": "application/json" },
27
+
method: "POST"
28
+
});
29
+
const data = await response.json();
30
+
31
+
console.log(data);
32
+
} catch (error) {
33
+
} finally {
34
+
setIsLoggingIn(false);
35
+
}
36
+
};
37
+
15
38
const scp = async () => {
16
39
const response = await fetch(`/api/lastfm?username=${usernameInput}`);
17
40
const data = await response.json();
···
19
42
setLastFMUsername(usernameInput);
20
43
setUsernameInput("");
21
44
22
-
console.log(data)
45
+
console.log(data);
23
46
24
47
const mostRecentlyScrobbledTrack = data?.recenttracks?.track?.[0];
25
48
···
83
106
/>
84
107
</div>
85
108
<Button
86
-
label="Log In"
87
-
onClick={async () => {}}
109
+
label={isLoggingIn ? "Logging In..." : "Log In"}
110
+
onClick={loginToATProto}
88
111
width="w-1/2"
89
112
/>
90
113
</div>
+140
-1
package-lock.json
+140
-1
package-lock.json
···
8
8
"name": "scrobbletobio",
9
9
"version": "0.1.0",
10
10
"dependencies": {
11
+
"@atproto/api": "^0.17.7",
12
+
"lucide-react": "^0.548.0",
11
13
"next": "16.0.1",
12
14
"react": "19.2.0",
13
15
"react-dom": "19.2.0"
···
36
38
"url": "https://github.com/sponsors/sindresorhus"
37
39
}
38
40
},
41
+
"node_modules/@atproto/api": {
42
+
"version": "0.17.7",
43
+
"resolved": "https://registry.npmjs.org/@atproto/api/-/api-0.17.7.tgz",
44
+
"integrity": "sha512-V+OJBZq9chcrD21xk1bUa6oc5DSKfQj5DmUPf5rmZncqL1w9ZEbS38H5cMyqqdhfgo2LWeDRdZHD0rvNyJsIaw==",
45
+
"license": "MIT",
46
+
"dependencies": {
47
+
"@atproto/common-web": "^0.4.3",
48
+
"@atproto/lexicon": "^0.5.1",
49
+
"@atproto/syntax": "^0.4.1",
50
+
"@atproto/xrpc": "^0.7.5",
51
+
"await-lock": "^2.2.2",
52
+
"multiformats": "^9.9.0",
53
+
"tlds": "^1.234.0",
54
+
"zod": "^3.23.8"
55
+
}
56
+
},
57
+
"node_modules/@atproto/api/node_modules/zod": {
58
+
"version": "3.25.76",
59
+
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
60
+
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
61
+
"license": "MIT",
62
+
"funding": {
63
+
"url": "https://github.com/sponsors/colinhacks"
64
+
}
65
+
},
66
+
"node_modules/@atproto/common-web": {
67
+
"version": "0.4.3",
68
+
"resolved": "https://registry.npmjs.org/@atproto/common-web/-/common-web-0.4.3.tgz",
69
+
"integrity": "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg==",
70
+
"license": "MIT",
71
+
"dependencies": {
72
+
"graphemer": "^1.4.0",
73
+
"multiformats": "^9.9.0",
74
+
"uint8arrays": "3.0.0",
75
+
"zod": "^3.23.8"
76
+
}
77
+
},
78
+
"node_modules/@atproto/common-web/node_modules/zod": {
79
+
"version": "3.25.76",
80
+
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
81
+
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
82
+
"license": "MIT",
83
+
"funding": {
84
+
"url": "https://github.com/sponsors/colinhacks"
85
+
}
86
+
},
87
+
"node_modules/@atproto/lexicon": {
88
+
"version": "0.5.1",
89
+
"resolved": "https://registry.npmjs.org/@atproto/lexicon/-/lexicon-0.5.1.tgz",
90
+
"integrity": "sha512-y8AEtYmfgVl4fqFxqXAeGvhesiGkxiy3CWoJIfsFDDdTlZUC8DFnZrYhcqkIop3OlCkkljvpSJi1hbeC1tbi8A==",
91
+
"license": "MIT",
92
+
"dependencies": {
93
+
"@atproto/common-web": "^0.4.3",
94
+
"@atproto/syntax": "^0.4.1",
95
+
"iso-datestring-validator": "^2.2.2",
96
+
"multiformats": "^9.9.0",
97
+
"zod": "^3.23.8"
98
+
}
99
+
},
100
+
"node_modules/@atproto/lexicon/node_modules/zod": {
101
+
"version": "3.25.76",
102
+
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
103
+
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
104
+
"license": "MIT",
105
+
"funding": {
106
+
"url": "https://github.com/sponsors/colinhacks"
107
+
}
108
+
},
109
+
"node_modules/@atproto/syntax": {
110
+
"version": "0.4.1",
111
+
"resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.4.1.tgz",
112
+
"integrity": "sha512-CJdImtLAiFO+0z3BWTtxwk6aY5w4t8orHTMVJgkf++QRJWTxPbIFko/0hrkADB7n2EruDxDSeAgfUGehpH6ngw==",
113
+
"license": "MIT"
114
+
},
115
+
"node_modules/@atproto/xrpc": {
116
+
"version": "0.7.5",
117
+
"resolved": "https://registry.npmjs.org/@atproto/xrpc/-/xrpc-0.7.5.tgz",
118
+
"integrity": "sha512-MUYNn5d2hv8yVegRL0ccHvTHAVj5JSnW07bkbiaz96UH45lvYNRVwt44z+yYVnb0/mvBzyD3/ZQ55TRGt7fHkA==",
119
+
"license": "MIT",
120
+
"dependencies": {
121
+
"@atproto/lexicon": "^0.5.1",
122
+
"zod": "^3.23.8"
123
+
}
124
+
},
125
+
"node_modules/@atproto/xrpc/node_modules/zod": {
126
+
"version": "3.25.76",
127
+
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
128
+
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
129
+
"license": "MIT",
130
+
"funding": {
131
+
"url": "https://github.com/sponsors/colinhacks"
132
+
}
133
+
},
39
134
"node_modules/@babel/code-frame": {
40
135
"version": "7.27.1",
41
136
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
···
2399
2494
"url": "https://github.com/sponsors/ljharb"
2400
2495
}
2401
2496
},
2497
+
"node_modules/await-lock": {
2498
+
"version": "2.2.2",
2499
+
"resolved": "https://registry.npmjs.org/await-lock/-/await-lock-2.2.2.tgz",
2500
+
"integrity": "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==",
2501
+
"license": "MIT"
2502
+
},
2402
2503
"node_modules/axe-core": {
2403
2504
"version": "4.11.0",
2404
2505
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.0.tgz",
···
3804
3905
"version": "1.4.0",
3805
3906
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
3806
3907
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
3807
-
"dev": true,
3808
3908
"license": "MIT"
3809
3909
},
3810
3910
"node_modules/has-bigints": {
···
4399
4499
"dev": true,
4400
4500
"license": "ISC"
4401
4501
},
4502
+
"node_modules/iso-datestring-validator": {
4503
+
"version": "2.2.2",
4504
+
"resolved": "https://registry.npmjs.org/iso-datestring-validator/-/iso-datestring-validator-2.2.2.tgz",
4505
+
"integrity": "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==",
4506
+
"license": "MIT"
4507
+
},
4402
4508
"node_modules/iterator.prototype": {
4403
4509
"version": "1.1.5",
4404
4510
"resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz",
···
4861
4967
"yallist": "^3.0.2"
4862
4968
}
4863
4969
},
4970
+
"node_modules/lucide-react": {
4971
+
"version": "0.548.0",
4972
+
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.548.0.tgz",
4973
+
"integrity": "sha512-63b16z63jM9yc1MwxajHeuu0FRZFsDtljtDjYm26Kd86UQ5HQzu9ksEtoUUw4RBuewodw/tGFmvipePvRsKeDA==",
4974
+
"license": "ISC",
4975
+
"peerDependencies": {
4976
+
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
4977
+
}
4978
+
},
4864
4979
"node_modules/magic-string": {
4865
4980
"version": "0.30.21",
4866
4981
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
···
4934
5049
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
4935
5050
"dev": true,
4936
5051
"license": "MIT"
5052
+
},
5053
+
"node_modules/multiformats": {
5054
+
"version": "9.9.0",
5055
+
"resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz",
5056
+
"integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==",
5057
+
"license": "(Apache-2.0 AND MIT)"
4937
5058
},
4938
5059
"node_modules/nanoid": {
4939
5060
"version": "3.3.11",
···
6112
6233
"url": "https://github.com/sponsors/jonschlinkert"
6113
6234
}
6114
6235
},
6236
+
"node_modules/tlds": {
6237
+
"version": "1.261.0",
6238
+
"resolved": "https://registry.npmjs.org/tlds/-/tlds-1.261.0.tgz",
6239
+
"integrity": "sha512-QXqwfEl9ddlGBaRFXIvNKK6OhipSiLXuRuLJX5DErz0o0Q0rYxulWLdFryTkV5PkdZct5iMInwYEGe/eR++1AA==",
6240
+
"license": "MIT",
6241
+
"bin": {
6242
+
"tlds": "bin.js"
6243
+
}
6244
+
},
6115
6245
"node_modules/to-regex-range": {
6116
6246
"version": "5.0.1",
6117
6247
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
···
6297
6427
"peerDependencies": {
6298
6428
"eslint": "^8.57.0 || ^9.0.0",
6299
6429
"typescript": ">=4.8.4 <6.0.0"
6430
+
}
6431
+
},
6432
+
"node_modules/uint8arrays": {
6433
+
"version": "3.0.0",
6434
+
"resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.0.0.tgz",
6435
+
"integrity": "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==",
6436
+
"license": "MIT",
6437
+
"dependencies": {
6438
+
"multiformats": "^9.4.2"
6300
6439
}
6301
6440
},
6302
6441
"node_modules/unbox-primitive": {
+8
-6
package.json
+8
-6
package.json
···
9
9
"lint": "eslint"
10
10
},
11
11
"dependencies": {
12
+
"@atproto/api": "^0.17.7",
13
+
"lucide-react": "^0.548.0",
14
+
"next": "16.0.1",
12
15
"react": "19.2.0",
13
-
"react-dom": "19.2.0",
14
-
"next": "16.0.1"
16
+
"react-dom": "19.2.0"
15
17
},
16
18
"devDependencies": {
17
-
"typescript": "^5",
19
+
"@tailwindcss/postcss": "^4",
18
20
"@types/node": "^20",
19
21
"@types/react": "^19",
20
22
"@types/react-dom": "^19",
21
-
"@tailwindcss/postcss": "^4",
23
+
"eslint": "^9",
24
+
"eslint-config-next": "16.0.1",
22
25
"tailwindcss": "^4",
23
-
"eslint": "^9",
24
-
"eslint-config-next": "16.0.1"
26
+
"typescript": "^5"
25
27
}
26
28
}