feat: reject token if it's not valid
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
import { DateTime } from "luxon";
|
||||
|
||||
import { beforeEach, describe, expect, it } from "bun:test";
|
||||
import { beforeEach, describe, expect, it, mock } from "bun:test";
|
||||
|
||||
import app from "~/index";
|
||||
import { getTestDb } from "~/libs/test/getTestDb";
|
||||
@@ -16,6 +16,9 @@ describe("requests the /token route", () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await resetTestDb();
|
||||
mock.module("src/libs/fcm/verifyFcmToken", () => ({
|
||||
verifyFcmToken: () => true,
|
||||
}));
|
||||
});
|
||||
|
||||
it("should succeed", async () => {
|
||||
@@ -191,4 +194,42 @@ describe("requests the /token route", () => {
|
||||
|
||||
expect(row).toBeUndefined();
|
||||
});
|
||||
|
||||
it("token is invalid, should fail", async () => {
|
||||
mock.module("src/libs/fcm/verifyFcmToken", () => ({
|
||||
verifyFcmToken: () => false,
|
||||
}));
|
||||
|
||||
const res = await app.request("/token", {
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
body: JSON.stringify({ token: "123", deviceId: "124", username: null }),
|
||||
});
|
||||
|
||||
expect(res.json()).resolves.toEqual({ success: false });
|
||||
expect(res.status).toBe(401);
|
||||
});
|
||||
|
||||
it("token is invalid, should not insert new entry", async () => {
|
||||
mock.module("src/libs/fcm/verifyFcmToken", () => ({
|
||||
verifyFcmToken: () => false,
|
||||
}));
|
||||
await app.request("/token", {
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
body: JSON.stringify({ token: "123", deviceId: "124", username: null }),
|
||||
});
|
||||
|
||||
const row = await db
|
||||
.select()
|
||||
.from(deviceTokensTable)
|
||||
.where(eq(deviceTokensTable.deviceId, "124"))
|
||||
.get();
|
||||
|
||||
expect(row).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
||||
import { env } from "hono/adapter";
|
||||
import mapKeys from "lodash.mapkeys";
|
||||
|
||||
import { Case, changeStringCase } from "~/libs/changeStringCase";
|
||||
import type { AdminSdkCredentials } from "~/libs/fcm/getGoogleAuthToken";
|
||||
import { verifyFcmToken } from "~/libs/fcm/verifyFcmToken";
|
||||
import { readEnvVariable } from "~/libs/readEnvVariable";
|
||||
import { saveToken } from "~/models/token";
|
||||
import type { Env } from "~/types/env";
|
||||
import {
|
||||
@@ -51,8 +56,20 @@ app.openapi(route, async (c) => {
|
||||
await c.req.json<typeof SaveTokenRequest._type>();
|
||||
|
||||
try {
|
||||
const isValidToken = await verifyFcmToken(
|
||||
token,
|
||||
mapKeys(
|
||||
readEnvVariable<AdminSdkCredentials>(c.env, "ADMIN_SDK_JSON"),
|
||||
(_, key) => changeStringCase(key, Case.snake_case, Case.camelCase),
|
||||
) as unknown as AdminSdkCredentials,
|
||||
);
|
||||
if (!isValidToken) {
|
||||
return c.json(ErrorResponse, 401);
|
||||
}
|
||||
|
||||
await saveToken(env(c, "workerd"), deviceId, token, username);
|
||||
} catch (error) {
|
||||
// when token already exists in the database
|
||||
if (
|
||||
error.code === "SQLITE_CONSTRAINT" &&
|
||||
error.message.includes("device_tokens.token")
|
||||
|
||||
Reference in New Issue
Block a user