+2
-3
app/routes/client-metadata[.json].tsx
+2
-3
app/routes/client-metadata[.json].tsx
+2
-3
app/routes/jwks[.json].tsx
+2
-3
app/routes/jwks[.json].tsx
+1
-2
app/routes/login.tsx
+1
-2
app/routes/login.tsx
···
5
import { LoginForm } from "~/features/login/login-form";
6
import { RouteToaster } from "~/features/toast/route";
7
import { i18nServer } from "~/i18n/i18n";
8
-
import { createOAuthClient } from "~/server/oauth/client";
9
import { getSessionUserDid } from "~/server/oauth/session";
10
import { createLogger } from "~/utils/logger";
11
···
21
return { error: t("login.unknown-error") };
22
}
23
try {
24
-
const oauthClient = await createOAuthClient();
25
const url = await oauthClient.authorize(handle, {
26
scope: "atproto transition:generic",
27
});
···
5
import { LoginForm } from "~/features/login/login-form";
6
import { RouteToaster } from "~/features/toast/route";
7
import { i18nServer } from "~/i18n/i18n";
8
+
import { oauthClient } from "~/server/oauth/client";
9
import { getSessionUserDid } from "~/server/oauth/session";
10
import { createLogger } from "~/utils/logger";
11
···
21
return { error: t("login.unknown-error") };
22
}
23
try {
24
const url = await oauthClient.authorize(handle, {
25
scope: "atproto transition:generic",
26
});
+1
-2
app/routes/oauth.callback.tsx
+1
-2
app/routes/oauth.callback.tsx
···
1
import { redirect } from "react-router";
2
3
-
import { createOAuthClient } from "~/server/oauth/client";
4
import { commitSession, getSession } from "~/server/oauth/session";
5
import { createLogger } from "~/utils/logger";
6
···
11
export async function loader({ request }: Route.LoaderArgs) {
12
const remixSession = await getSession(request);
13
try {
14
-
const oauthClient = await createOAuthClient();
15
const { session: oauthSession } = await oauthClient.callback(
16
new URL(request.url).searchParams,
17
);
···
1
import { redirect } from "react-router";
2
3
+
import { oauthClient } from "~/server/oauth/client";
4
import { commitSession, getSession } from "~/server/oauth/session";
5
import { createLogger } from "~/utils/logger";
6
···
11
export async function loader({ request }: Route.LoaderArgs) {
12
const remixSession = await getSession(request);
13
try {
14
const { session: oauthSession } = await oauthClient.callback(
15
new URL(request.url).searchParams,
16
);
+31
-39
app/server/oauth/client.ts
+31
-39
app/server/oauth/client.ts
···
6
7
import { SessionStore, StateStore } from "./storage";
8
9
-
let oauthClient: NodeOAuthClient | null = null;
10
11
-
export const createOAuthClient = async () => {
12
-
if (oauthClient) {
13
-
return oauthClient;
14
-
}
15
-
const baseUrl = isProduction ? env.PUBLIC_URL : "http://127.0.0.1:3000";
16
-
const privateKeyPKCS8 = Buffer.from(
17
-
env.PRIVATE_KEY_ES256_B64,
18
-
"base64",
19
-
).toString();
20
-
const privateKey = await JoseKey.fromImportable(privateKeyPKCS8, "key1");
21
-
const oauthClientOptions: NodeOAuthClientOptions = {
22
-
clientMetadata: {
23
-
client_name: "Linkat",
24
-
client_id: isProduction
25
-
? `${env.PUBLIC_URL}/client-metadata.json`
26
-
: `http://localhost?redirect_uri=${encodeURIComponent(`${baseUrl}/oauth/callback`)}`,
27
-
client_uri: baseUrl,
28
-
jwks_uri: `${baseUrl}/jwks.json`,
29
-
redirect_uris: [`${baseUrl}/oauth/callback`],
30
-
scope: "atproto transition:generic",
31
-
grant_types: ["authorization_code", "refresh_token"],
32
-
response_types: ["code"],
33
-
application_type: "web",
34
-
token_endpoint_auth_method: "private_key_jwt",
35
-
token_endpoint_auth_signing_alg: "ES256",
36
-
dpop_bound_access_tokens: true,
37
-
},
38
-
keyset: [privateKey],
39
-
plcDirectoryUrl: env.ATPROTO_PLC_URL,
40
-
stateStore: new StateStore(),
41
-
sessionStore: new SessionStore(),
42
-
};
43
-
if (!isProduction) {
44
-
oauthClientOptions.handleResolver = env.BSKY_PUBLIC_API_URL;
45
-
oauthClientOptions.allowHttp = true; // httpを許可しないとOAuthProtectedResourceMetadataResolverがエラーを投げる
46
-
}
47
-
oauthClient = new NodeOAuthClient(oauthClientOptions);
48
-
return oauthClient;
49
};
···
6
7
import { SessionStore, StateStore } from "./storage";
8
9
+
const baseUrl = isProduction ? env.PUBLIC_URL : "http://127.0.0.1:3000";
10
11
+
const privateKey = Buffer.from(env.PRIVATE_KEY_ES256_B64, "base64").toString();
12
+
13
+
const oauthClientOptions: NodeOAuthClientOptions = {
14
+
clientMetadata: {
15
+
client_name: "Linkat",
16
+
client_id: isProduction
17
+
? `${env.PUBLIC_URL}/client-metadata.json`
18
+
: `http://localhost?redirect_uri=${encodeURIComponent(`${baseUrl}/oauth/callback`)}`,
19
+
client_uri: baseUrl,
20
+
jwks_uri: `${baseUrl}/jwks.json`,
21
+
redirect_uris: [`${baseUrl}/oauth/callback`],
22
+
scope: "atproto transition:generic",
23
+
grant_types: ["authorization_code", "refresh_token"],
24
+
response_types: ["code"],
25
+
application_type: "web",
26
+
token_endpoint_auth_method: "private_key_jwt",
27
+
token_endpoint_auth_signing_alg: "ES256",
28
+
dpop_bound_access_tokens: true,
29
+
},
30
+
keyset: [await JoseKey.fromImportable(privateKey, "key1")],
31
+
plcDirectoryUrl: env.ATPROTO_PLC_URL,
32
+
stateStore: new StateStore(),
33
+
sessionStore: new SessionStore(),
34
};
35
+
36
+
if (!isProduction) {
37
+
oauthClientOptions.handleResolver = env.BSKY_PUBLIC_API_URL;
38
+
oauthClientOptions.allowHttp = true; // httpを許可しないとOAuthProtectedResourceMetadataResolverがエラーを投げる
39
+
}
40
+
41
+
export const oauthClient = new NodeOAuthClient(oauthClientOptions);
+1
-2
app/server/oauth/session.ts
+1
-2
app/server/oauth/session.ts
···
4
import { userService } from "~/server/service/userService";
5
import { env } from "~/utils/env";
6
7
-
import { createOAuthClient } from "./client";
8
9
type SessionData = {
10
did: string;
···
56
if (!userDid) {
57
return null;
58
}
59
-
const oauthClient = await createOAuthClient();
60
const oauthSession = await oauthClient.restore(userDid);
61
return new LinkatAgent(oauthSession);
62
};
···
4
import { userService } from "~/server/service/userService";
5
import { env } from "~/utils/env";
6
7
+
import { oauthClient } from "./client";
8
9
type SessionData = {
10
did: string;
···
56
if (!userDid) {
57
return null;
58
}
59
const oauthSession = await oauthClient.restore(userDid);
60
return new LinkatAgent(oauthSession);
61
};
+3
vite.config.ts
+3
vite.config.ts