fix(web): токен с недопустимыми символами — экран входа, а не «хаб не отвечает» (#21)
Сохранённый в localStorage токен с кириллицей, пробелом или переводом строки давал TypeError у fetch, который превращался в HubDownError. Теперь call() проверяет TOKEN_RE до запроса и бросает AuthError. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
51c2772dcc
commit
c124e082ae
@ -41,6 +41,13 @@ describe("api", () => {
|
|||||||
expect(fetch).not.toHaveBeenCalled();
|
expect(fetch).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("токен с недопустимыми символами — AuthError без запроса", async () => {
|
||||||
|
setToken("ток ен");
|
||||||
|
const fetch = mockFetch(() => json(200, {}));
|
||||||
|
await expect(api.get("/board")).rejects.toBeInstanceOf(AuthError);
|
||||||
|
expect(fetch).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it("checkToken проверяет переданный токен, не сохранённый", async () => {
|
it("checkToken проверяет переданный токен, не сохранённый", async () => {
|
||||||
const fetch = mockFetch(() => json(200, { kind_labels: {} }));
|
const fetch = mockFetch(() => json(200, { kind_labels: {} }));
|
||||||
await checkToken("candidate");
|
await checkToken("candidate");
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// единственный клиент HTTP API хаба: тот же хост, клиентский токен в Authorization, ответы — JSON.
|
// единственный клиент HTTP API хаба: тот же хост, клиентский токен в Authorization, ответы — JSON.
|
||||||
// Ошибки: AuthError — 401 или нет токена; HubDownError — сеть или 5xx; ApiError — прочие 4xx с {error, detail}
|
// Ошибки: AuthError — 401 или нет токена; HubDownError — сеть или 5xx; ApiError — прочие 4xx с {error, detail}
|
||||||
import { getToken } from "../auth/token.ts";
|
import { getToken, TOKEN_RE } from "../auth/token.ts";
|
||||||
import type { HubSettings } from "./types.ts";
|
import type { HubSettings } from "./types.ts";
|
||||||
|
|
||||||
export class AuthError extends Error {}
|
export class AuthError extends Error {}
|
||||||
@ -29,6 +29,8 @@ function withParams(path: string, params?: Params): string {
|
|||||||
|
|
||||||
async function call<T>(method: string, path: string, body?: unknown, token = getToken()): Promise<T> {
|
async function call<T>(method: string, path: string, body?: unknown, token = getToken()): Promise<T> {
|
||||||
if (!token) throw new AuthError("нет токена");
|
if (!token) throw new AuthError("нет токена");
|
||||||
|
// токен с недопустимыми символами (например, оставленный прежней доской) — сразу на экран входа, а не «хаб не отвечает»
|
||||||
|
if (!TOKEN_RE.test(token)) throw new AuthError("недопустимые символы в токене");
|
||||||
const headers: Record<string, string> = { Authorization: "Bearer " + token, Accept: "application/json" };
|
const headers: Record<string, string> = { Authorization: "Bearer " + token, Accept: "application/json" };
|
||||||
if (body !== undefined) headers["Content-Type"] = "application/json; charset=utf-8";
|
if (body !== undefined) headers["Content-Type"] = "application/json; charset=utf-8";
|
||||||
let resp: Response;
|
let resp: Response;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user