···
import { createStore } from "solid-js/store";
11
-
import { XRPC } from "@atcute/client";
11
+
import { CredentialManager, XRPC } from "@atcute/client";
···
const [loginState, setLoginState] = createSignal(false);
let agent: OAuthUserAgent;
58
+
let manager: CredentialManager;
59
+
let agentDID: string;
const resolveDid = async (did: string) => {
···
const Login: Component = () => {
const [loginInput, setLoginInput] = createSignal("");
82
+
const [password, setPassword] = createSignal("");
const [handle, setHandle] = createSignal("");
const [notice, setNotice] = createSignal("");
···
agent = new OAuthUserAgent(session);
rpc = new XRPC({ handler: agent });
119
+
agentDID = agent.sub;
setHandle(await resolveDid(agent.sub));
···
124
-
const loginBsky = async (handle: string) => {
126
-
setNotice(`Resolving your identity...`);
127
-
const resolved = await resolveFromIdentity(handle);
128
+
const getPDS = async (did: string) => {
129
+
const res = await fetch(
130
+
did.startsWith("did:web") ?
131
+
`https://${did.split(":")[2]}/.well-known/did.json`
132
+
: "https://plc.directory/" + did,
135
+
return res.json().then((doc: any) => {
136
+
for (const service of doc.service) {
137
+
if (service.id === "#atproto_pds") return service.serviceEndpoint;
142
+
const resolveHandle = async (handle: string) => {
143
+
const rpc = new XRPC({
144
+
handler: new CredentialManager({
145
+
service: "https://public.api.bsky.app",
148
+
const res = await rpc.get("com.atproto.identity.resolveHandle", {
149
+
params: { handle: handle },
151
+
return res.data.did;
154
+
const loginBsky = async (login: string) => {
156
+
agentDID = login.startsWith("did:") ? login : await resolveHandle(login);
157
+
manager = new CredentialManager({ service: await getPDS(agentDID) });
158
+
rpc = new XRPC({ handler: manager });
129
-
setNotice(`Contacting your data server...`);
130
-
const authUrl = await createAuthorizationUrl({
131
-
scope: import.meta.env.VITE_OAUTH_SCOPE,
160
+
await manager.login({
161
+
identifier: agentDID,
162
+
password: password(),
164
+
setLoginState(true);
167
+
setNotice(`Resolving your identity...`);
168
+
const resolved = await resolveFromIdentity(login);
170
+
setNotice(`Contacting your data server...`);
171
+
const authUrl = await createAuthorizationUrl({
172
+
scope: import.meta.env.VITE_OAUTH_SCOPE,
135
-
setNotice(`Redirecting...`);
136
-
await new Promise((resolve) => setTimeout(resolve, 250));
176
+
setNotice(`Redirecting...`);
177
+
await new Promise((resolve) => setTimeout(resolve, 250));
138
-
location.assign(authUrl);
140
-
setNotice("Error during OAuth login");
179
+
location.assign(authUrl);
181
+
setNotice("Error during OAuth login");
···
class="dark:bg-dark-100 mb-2 rounded-lg border border-gray-400 px-2 py-1 focus:outline-none focus:ring-1 focus:ring-gray-300"
onInput={(e) => setLoginInput(e.currentTarget.value)}
205
+
<label for="password" class="ml-0.5">
211
+
placeholder="leave empty for oauth"
212
+
class="dark:bg-dark-100 mb-2 rounded-lg border border-gray-400 px-2 py-1 focus:outline-none focus:ring-1 focus:ring-gray-300"
213
+
onInput={(e) => setPassword(e.currentTarget.value)}
onclick={() => loginBsky(loginInput())}
class="rounded bg-blue-600 py-1.5 font-bold text-slate-100 hover:bg-blue-700"
···
171
-
<p>Remember to use your main password, not an app password.</p>
172
-
<p>The session is only stored on your browser.</p>
173
-
<p>Make sure to check the URL you will be authenticated through.</p>
175
-
(<b>bsky.social</b> unless you are on a selfhosted server)
<Show when={loginState() && handle()}>
···
const fetchPage = async (cursor?: string) => {
return await rpc.get("com.atproto.repo.listRecords", {
collection: "app.bsky.graph.follow",
···
viewer.blocking || viewer.blockingByList ?
RepoStatus.BLOCKEDBY | RepoStatus.BLOCKING
256
-
} else if (res.data.did.includes(agent.sub)) {
300
+
} else if (res.data.did.includes(agentDID)) {
status = RepoStatus.YOURSELF;
} else if (viewer.blocking || viewer.blockingByList) {
status = RepoStatus.BLOCKING;
···
for (let i = 0; i < writes.length; i += BATCHSIZE) {
await rpc.call("com.atproto.repo.applyWrites", {
writes: writes.slice(i, i + BATCHSIZE),