+1
-5
app/routes/$handle.tsx
+1
-5
app/routes/$handle.tsx
···
15
};
16
17
export async function loader({ request, params }: Route.LoaderArgs) {
18
-
const maybeHandle = params.handle;
19
-
if (!maybeHandle || !maybeHandle.includes(".")) {
20
-
return notFound();
21
-
}
22
// この順で処理した場合ボードを持たない(=このサービスのユーザーでない)ユーザーの
23
// データも作られてしまうが、一旦このままにしておく
24
const user = await userService.findOrFetchUser({
25
-
handleOrDid: maybeHandle,
26
});
27
if (!user) {
28
return notFound();
+18
app/server/service/userService/user.spec.ts
+18
app/server/service/userService/user.spec.ts
···
154
// assert
155
expect(actual).toBeNull();
156
});
157
+
test("入力が明らかにドメインでなければnullを返す", async () => {
158
+
// arrange
159
+
// act
160
+
const actual = await userService.findOrFetchUser({
161
+
handleOrDid: "invalid",
162
+
});
163
+
// assert
164
+
expect(actual).toBeNull();
165
+
});
166
+
test("入力がDIDとして不正であればnullを返す", async () => {
167
+
// arrange
168
+
// act
169
+
const actual = await userService.findOrFetchUser({
170
+
handleOrDid: "did:plc:invalid",
171
+
});
172
+
// assert
173
+
expect(actual).toBeNull();
174
+
});
175
});
176
});
+4
app/server/service/userService/user.ts
+4
app/server/service/userService/user.ts
···
1
import type { AppBskyActorDefs } from "@atproto/api";
2
import type { Prisma, User } from "@prisma/client";
3
4
import { LinkatAgent } from "~/libs/agent";
···
72
tx?: Prisma.TransactionClient;
73
handleOrDid: string;
74
}) => {
75
const user = await findUser({ tx, handleOrDid });
76
if (user && !shouldRefetch(user)) {
77
return user;
···
1
import type { AppBskyActorDefs } from "@atproto/api";
2
+
import { isDid } from "@atproto/did";
3
import type { Prisma, User } from "@prisma/client";
4
5
import { LinkatAgent } from "~/libs/agent";
···
73
tx?: Prisma.TransactionClient;
74
handleOrDid: string;
75
}) => {
76
+
if (!handleOrDid.includes(".") && !isDid(handleOrDid)) {
77
+
return null;
78
+
}
79
const user = await findUser({ tx, handleOrDid });
80
if (user && !shouldRefetch(user)) {
81
return user;
+1
package.json
+1
package.json
+10
pnpm-lock.yaml
+10
pnpm-lock.yaml
···
11
'@atproto/api':
12
specifier: 0.13.18
13
version: 0.13.18
14
'@atproto/identity':
15
specifier: 0.4.3
16
version: 0.4.3
···
309
310
'@atproto/did@0.1.2':
311
resolution: {integrity: sha512-gmY1SyAuqfmsFbIXkUIScfnULqn39FoUNz4oE0fUuMu9in6PEyoxlmD2lAo7Q3KMy3X/hvTn2u5f8W/2KuDg1w==}
312
313
'@atproto/identity@0.4.3':
314
resolution: {integrity: sha512-DLXMWh57dHvIeBl+IvC+q20z0IdDZT1awOn84vDyxacL9DfhbiTy/zCUPFEzHyvfrilNG1tDA4zQzURubdFqNg==}
···
5280
uint8arrays: 3.0.0
5281
5282
'@atproto/did@0.1.2':
5283
dependencies:
5284
zod: 3.23.8
5285
···
11
'@atproto/api':
12
specifier: 0.13.18
13
version: 0.13.18
14
+
'@atproto/did':
15
+
specifier: 0.1.3
16
+
version: 0.1.3
17
'@atproto/identity':
18
specifier: 0.4.3
19
version: 0.4.3
···
312
313
'@atproto/did@0.1.2':
314
resolution: {integrity: sha512-gmY1SyAuqfmsFbIXkUIScfnULqn39FoUNz4oE0fUuMu9in6PEyoxlmD2lAo7Q3KMy3X/hvTn2u5f8W/2KuDg1w==}
315
+
316
+
'@atproto/did@0.1.3':
317
+
resolution: {integrity: sha512-ULD8Gw/KRRwLFZ2Z2L4DjmdOMrg8IYYlcjdSc+GQ2/QJSVnD2zaJJVTLd3vls121wGt/583rNaiZTT2DpBze4w==}
318
319
'@atproto/identity@0.4.3':
320
resolution: {integrity: sha512-DLXMWh57dHvIeBl+IvC+q20z0IdDZT1awOn84vDyxacL9DfhbiTy/zCUPFEzHyvfrilNG1tDA4zQzURubdFqNg==}
···
5286
uint8arrays: 3.0.0
5287
5288
'@atproto/did@0.1.2':
5289
+
dependencies:
5290
+
zod: 3.23.8
5291
+
5292
+
'@atproto/did@0.1.3':
5293
dependencies:
5294
zod: 3.23.8
5295