Skip to content

Commit 9eef354

Browse files
committed
Apply errors-plugin to login mutations
1 parent 64c1bf4 commit 9eef354

File tree

8 files changed

+188
-76
lines changed

8 files changed

+188
-76
lines changed

graphql/login.ts

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,34 @@ import { createMessage, type Message } from "@upyo/core";
1919
import { sql } from "drizzle-orm";
2020
import { parseTemplate } from "url-template";
2121
import { Account } from "./account.ts";
22-
import { builder } from "./builder.ts";
23-
import { SessionRef } from "./session.ts";
22+
import { builder, type ValuesOfEnumType } from "./builder.ts";
2423
import { EMAIL_FROM } from "./email.ts";
24+
import { SessionRef } from "./session.ts";
2525

2626
const logger = getLogger(["hackerspub", "graphql", "login"]);
2727

28+
const LoginErrorKind = builder.enumType("LoginErrorKind", {
29+
values: ["ACCOUNT_NOT_FOUND"] as const,
30+
});
31+
32+
class LoginError extends Error {
33+
public constructor(
34+
public readonly kind: ValuesOfEnumType<typeof LoginErrorKind>,
35+
) {
36+
super(`Login error - ${kind}`);
37+
}
38+
}
39+
40+
builder.objectType(LoginError, {
41+
name: "LoginError",
42+
fields: (t) => ({
43+
loginErrorKind: t.field({
44+
type: LoginErrorKind,
45+
resolve: (error) => error.kind,
46+
}),
47+
}),
48+
});
49+
2850
interface LoginChallenge {
2951
accountId: Uuid;
3052
token: Uuid;
@@ -54,7 +76,12 @@ LoginChallengeRef.implement({
5476
builder.mutationFields((t) => ({
5577
loginByUsername: t.field({
5678
type: LoginChallengeRef,
57-
nullable: true,
79+
errors: {
80+
types: [LoginError],
81+
result: {
82+
name: "LoginSuccess",
83+
},
84+
},
5885
args: {
5986
username: t.arg.string({
6087
required: true,
@@ -80,7 +107,9 @@ builder.mutationFields((t) => ({
80107
with: { emails: true },
81108
where: { username: args.username },
82109
});
83-
if (account == null) return null;
110+
if (account == null) {
111+
throw new LoginError("ACCOUNT_NOT_FOUND");
112+
}
84113
const token = await createSigninToken(ctx.kv, account.id);
85114
const messages: Message[] = [];
86115
for (const { email } of account.emails) {
@@ -110,7 +139,12 @@ builder.mutationFields((t) => ({
110139

111140
loginByEmail: t.field({
112141
type: LoginChallengeRef,
113-
nullable: true,
142+
errors: {
143+
types: [LoginError],
144+
result: {
145+
name: "LoginSuccess",
146+
},
147+
},
114148
args: {
115149
email: t.arg.string({
116150
required: true,
@@ -150,7 +184,9 @@ builder.mutationFields((t) => ({
150184
with: { emails: true },
151185
});
152186
}
153-
if (account == null) return null;
187+
if (account == null) {
188+
throw new LoginError("ACCOUNT_NOT_FOUND");
189+
}
154190
const token = await createSigninToken(ctx.kv, account.id);
155191
const messages: Message[] = [];
156192
for (const { email } of account.emails) {

graphql/schema.graphql

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,18 @@ type LoginChallenge {
375375
token: UUID!
376376
}
377377

378+
type LoginError {
379+
loginErrorKind: LoginErrorKind!
380+
}
381+
382+
enum LoginErrorKind {
383+
ACCOUNT_NOT_FOUND
384+
}
385+
386+
type LoginSuccess {
387+
data: LoginChallenge!
388+
}
389+
378390
"""A Hackers' Pub-flavored Markdown text."""
379391
scalar Markdown
380392

@@ -421,7 +433,7 @@ type Mutation {
421433
The RFC 6570-compliant URI Template for the verification link. Available variabvles: `{token}` and `{code}`.
422434
"""
423435
verifyUrl: URITemplate!
424-
): LoginChallenge
436+
): MutationLoginByUsernameResult!
425437
loginByUsername(
426438
"""The locale for the sign-in email."""
427439
locale: Locale!
@@ -433,7 +445,7 @@ type Mutation {
433445
The RFC 6570-compliant URI Template for the verification link. Available variabvles: `{token}` and `{code}`.
434446
"""
435447
verifyUrl: URITemplate!
436-
): LoginChallenge
448+
): MutationLoginByUsernameResult!
437449

438450
"""Revoke a session by its ID."""
439451
revokeSession(
@@ -443,6 +455,8 @@ type Mutation {
443455
updateAccount(input: UpdateAccountInput!): UpdateAccountPayload!
444456
}
445457

458+
union MutationLoginByUsernameResult = LoginError | LoginSuccess
459+
446460
interface Node {
447461
id: ID!
448462
}

web-next/src/locales/en-US/messages.po

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ msgstr "{0}'s notes"
128128
msgid "{0}'s shares"
129129
msgstr "{0}'s shares"
130130

131-
#: src/routes/sign/index.tsx:194
131+
#: src/routes/sign/index.tsx:180
132132
msgid "A sign-in link has been sent to your email. Please check your inbox (or spam folder)."
133133
msgstr "A sign-in link has been sent to your email. Please check your inbox (or spam folder)."
134134

@@ -172,19 +172,19 @@ msgstr "Creating account…"
172172
msgid "Display name"
173173
msgstr "Display name"
174174

175-
#: src/routes/sign/index.tsx:230
175+
#: src/routes/sign/index.tsx:272
176176
msgid "Do you need an account? Hackers' Pub is invite-only—please ask a friend to invite you."
177177
msgstr "Do you need an account? Hackers' Pub is invite-only—please ask a friend to invite you."
178178

179179
#: src/routes/sign/up/[token].tsx:351
180180
msgid "Email address"
181181
msgstr "Email address"
182182

183-
#: src/routes/sign/index.tsx:208
183+
#: src/routes/sign/index.tsx:250
184184
msgid "Email or username"
185185
msgstr "Email or username"
186186

187-
#: src/routes/sign/index.tsx:193
187+
#: src/routes/sign/index.tsx:188
188188
msgid "Enter your email or username below to sign in."
189189
msgstr "Enter your email or username below to sign in."
190190

@@ -346,7 +346,7 @@ msgstr "No posts found"
346346
#~ msgid "No posts found."
347347
#~ msgstr "No posts found."
348348

349-
#: src/routes/sign/index.tsx:192
349+
#: src/routes/sign/index.tsx:185
350350
msgid "No such account in Hackers' Pub—please try again."
351351
msgstr "No such account in Hackers' Pub—please try again."
352352

@@ -355,7 +355,7 @@ msgstr "No such account in Hackers' Pub—please try again."
355355
msgid "Notes"
356356
msgstr "Notes"
357357

358-
#: src/routes/sign/index.tsx:241
358+
#: src/routes/sign/index.tsx:283
359359
msgid "Or enter the code from the email"
360360
msgstr "Or enter the code from the email"
361361

@@ -389,7 +389,7 @@ msgid "Shares"
389389
msgstr "Shares"
390390

391391
#: src/components/AppSidebar.tsx:241
392-
#: src/routes/sign/index.tsx:224
392+
#: src/routes/sign/index.tsx:266
393393
msgid "Sign in"
394394
msgstr "Sign in"
395395

@@ -401,18 +401,22 @@ msgstr "Sign out"
401401
msgid "Sign up"
402402
msgstr "Sign up"
403403

404-
#: src/routes/sign/index.tsx:187
404+
#: src/routes/sign/index.tsx:233
405405
msgid "Signing in Hackers' Pub"
406406
msgstr "Signing in Hackers' Pub"
407407

408-
#: src/routes/sign/index.tsx:224
408+
#: src/routes/sign/index.tsx:266
409409
msgid "Signing in…"
410410
msgstr "Signing in…"
411411

412412
#: src/routes/sign/up/[token].tsx:327
413413
msgid "Signing up for Hackers' Pub"
414414
msgstr "Signing up for Hackers' Pub"
415415

416+
#: src/routes/sign/index.tsx:190
417+
msgid "Something went wrong—please try again."
418+
msgstr "Something went wrong—please try again."
419+
416420
#: src/components/ArticleCard.tsx:231
417421
msgid "Summarized by LLM"
418422
msgstr "Summarized by LLM"

web-next/src/locales/ja-JP/messages.po

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ msgstr "{0}さんの投稿"
128128
msgid "{0}'s shares"
129129
msgstr "{0}さんの共有"
130130

131-
#: src/routes/sign/index.tsx:194
131+
#: src/routes/sign/index.tsx:180
132132
msgid "A sign-in link has been sent to your email. Please check your inbox (or spam folder)."
133133
msgstr "ログインリンクがメールに送信されました。受信トレイ(または迷惑メールフォルダ)を確認してください。"
134134

@@ -172,19 +172,19 @@ msgstr "アカウントを作成中…"
172172
msgid "Display name"
173173
msgstr "名前"
174174

175-
#: src/routes/sign/index.tsx:230
175+
#: src/routes/sign/index.tsx:272
176176
msgid "Do you need an account? Hackers' Pub is invite-only—please ask a friend to invite you."
177177
msgstr "アカウントが必要ですか?Hackers' Pubは招待制ですので、友人に招待をお願いしてください。"
178178

179179
#: src/routes/sign/up/[token].tsx:351
180180
msgid "Email address"
181181
msgstr "メールアドレス"
182182

183-
#: src/routes/sign/index.tsx:208
183+
#: src/routes/sign/index.tsx:250
184184
msgid "Email or username"
185185
msgstr "メールアドレスまたはユーザー名"
186186

187-
#: src/routes/sign/index.tsx:193
187+
#: src/routes/sign/index.tsx:188
188188
msgid "Enter your email or username below to sign in."
189189
msgstr "以下にメールアドレスまたはユーザー名を入力してログインしてください。"
190190

@@ -346,7 +346,7 @@ msgstr "コンテンツはありません"
346346
#~ msgid "No posts found."
347347
#~ msgstr "コンテンツが見つかりませんでした。"
348348

349-
#: src/routes/sign/index.tsx:192
349+
#: src/routes/sign/index.tsx:185
350350
msgid "No such account in Hackers' Pub—please try again."
351351
msgstr "Hackers' Pubにそのようなアカウントはありません。もう一度お試しください。"
352352

@@ -355,7 +355,7 @@ msgstr "Hackers' Pubにそのようなアカウントはありません。もう
355355
msgid "Notes"
356356
msgstr "投稿"
357357

358-
#: src/routes/sign/index.tsx:241
358+
#: src/routes/sign/index.tsx:283
359359
msgid "Or enter the code from the email"
360360
msgstr "またはメールのコードを入力してください"
361361

@@ -389,7 +389,7 @@ msgid "Shares"
389389
msgstr "共有"
390390

391391
#: src/components/AppSidebar.tsx:241
392-
#: src/routes/sign/index.tsx:224
392+
#: src/routes/sign/index.tsx:266
393393
msgid "Sign in"
394394
msgstr "ログイン"
395395

@@ -401,18 +401,22 @@ msgstr "ログアウト"
401401
msgid "Sign up"
402402
msgstr "登録"
403403

404-
#: src/routes/sign/index.tsx:187
404+
#: src/routes/sign/index.tsx:233
405405
msgid "Signing in Hackers' Pub"
406406
msgstr "Hackers' Pubにログイン"
407407

408-
#: src/routes/sign/index.tsx:224
408+
#: src/routes/sign/index.tsx:266
409409
msgid "Signing in…"
410410
msgstr "ログイン中…"
411411

412412
#: src/routes/sign/up/[token].tsx:327
413413
msgid "Signing up for Hackers' Pub"
414414
msgstr "Hackers' Pubに登録"
415415

416+
#: src/routes/sign/index.tsx:190
417+
msgid "Something went wrong—please try again."
418+
msgstr "問題が発生しました。再度お試しください。"
419+
416420
#: src/components/ArticleCard.tsx:231
417421
msgid "Summarized by LLM"
418422
msgstr "LLMによる要約"

web-next/src/locales/ko-KR/messages.po

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ msgstr "{0} 님의 단문"
128128
msgid "{0}'s shares"
129129
msgstr "{0} 님의 공유"
130130

131-
#: src/routes/sign/index.tsx:194
131+
#: src/routes/sign/index.tsx:180
132132
msgid "A sign-in link has been sent to your email. Please check your inbox (or spam folder)."
133133
msgstr "로그인 링크가 이메일로 전송되었습니다. 받은 편지함(또는 스팸 폴더)을 확인해주세요."
134134

@@ -172,19 +172,19 @@ msgstr "계정을 생성하는 중…"
172172
msgid "Display name"
173173
msgstr "이름"
174174

175-
#: src/routes/sign/index.tsx:230
175+
#: src/routes/sign/index.tsx:272
176176
msgid "Do you need an account? Hackers' Pub is invite-only—please ask a friend to invite you."
177177
msgstr "계정이 필요하신가요? Hackers' Pub은 초대 전용입니다. 친구에게 초대를 요청해주세요."
178178

179179
#: src/routes/sign/up/[token].tsx:351
180180
msgid "Email address"
181181
msgstr "이메일 주소"
182182

183-
#: src/routes/sign/index.tsx:208
183+
#: src/routes/sign/index.tsx:250
184184
msgid "Email or username"
185185
msgstr "이메일 또는 아이디"
186186

187-
#: src/routes/sign/index.tsx:193
187+
#: src/routes/sign/index.tsx:188
188188
msgid "Enter your email or username below to sign in."
189189
msgstr "로그인하려면 아래에 이메일 또는 아이디를 입력해주세요."
190190

@@ -346,7 +346,7 @@ msgstr "콘텐츠가 없습니다"
346346
#~ msgid "No posts found."
347347
#~ msgstr "콘텐츠를 찾을 수 없습니다."
348348

349-
#: src/routes/sign/index.tsx:192
349+
#: src/routes/sign/index.tsx:185
350350
msgid "No such account in Hackers' Pub—please try again."
351351
msgstr "Hackers' Pub에 해당 계정이 없습니다. 다시 시도해주세요."
352352

@@ -355,7 +355,7 @@ msgstr "Hackers' Pub에 해당 계정이 없습니다. 다시 시도해주세요
355355
msgid "Notes"
356356
msgstr "단문"
357357

358-
#: src/routes/sign/index.tsx:241
358+
#: src/routes/sign/index.tsx:283
359359
msgid "Or enter the code from the email"
360360
msgstr "또는 이메일의 코드를 입력하세요"
361361

@@ -389,7 +389,7 @@ msgid "Shares"
389389
msgstr "공유"
390390

391391
#: src/components/AppSidebar.tsx:241
392-
#: src/routes/sign/index.tsx:224
392+
#: src/routes/sign/index.tsx:266
393393
msgid "Sign in"
394394
msgstr "로그인"
395395

@@ -401,18 +401,22 @@ msgstr "로그아웃"
401401
msgid "Sign up"
402402
msgstr "가입"
403403

404-
#: src/routes/sign/index.tsx:187
404+
#: src/routes/sign/index.tsx:233
405405
msgid "Signing in Hackers' Pub"
406406
msgstr "Hackers' Pub에 로그인"
407407

408-
#: src/routes/sign/index.tsx:224
408+
#: src/routes/sign/index.tsx:266
409409
msgid "Signing in…"
410410
msgstr "로그인 중…"
411411

412412
#: src/routes/sign/up/[token].tsx:327
413413
msgid "Signing up for Hackers' Pub"
414414
msgstr "Hackers' Pub 가입"
415415

416+
#: src/routes/sign/index.tsx:190
417+
msgid "Something went wrong—please try again."
418+
msgstr "문제가 발생했습니다. 다시 시도해주세요."
419+
416420
#: src/components/ArticleCard.tsx:231
417421
msgid "Summarized by LLM"
418422
msgstr "LLM 요약"

0 commit comments

Comments
 (0)