Compare commits
3 Commits
a2e5fa0ab9
...
2dba6c3597
| Author | SHA1 | Date | |
|---|---|---|---|
| 2dba6c3597 | |||
|
|
6ba7d678c6 | ||
|
|
dffb86007e |
3796
package-lock.json
generated
Normal file
3796
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@
|
|||||||
"@peculiar/asn1-ecc": "^2.7.0",
|
"@peculiar/asn1-ecc": "^2.7.0",
|
||||||
"@peculiar/asn1-schema": "^2.7.0",
|
"@peculiar/asn1-schema": "^2.7.0",
|
||||||
"cbor-x": "^1.6.4",
|
"cbor-x": "^1.6.4",
|
||||||
|
"cors": "^2.8.6",
|
||||||
"did-jwt": "^7.4.7",
|
"did-jwt": "^7.4.7",
|
||||||
"did-resolver": "^4.1.0",
|
"did-resolver": "^4.1.0",
|
||||||
"express": "^5.2.1",
|
"express": "^5.2.1",
|
||||||
@@ -22,6 +23,8 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/express": "^5.0.6",
|
"@types/express": "^5.0.6",
|
||||||
"@types/node": "^22.19.19",
|
"@types/node": "^22.19.19",
|
||||||
|
"@types/cors": "^2.8.19",
|
||||||
|
"tsx": "^4.19.2",
|
||||||
"typescript": "^5.9.3"
|
"typescript": "^5.9.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
pnpm-lock.yaml
generated
28
pnpm-lock.yaml
generated
@@ -17,6 +17,9 @@ importers:
|
|||||||
cbor-x:
|
cbor-x:
|
||||||
specifier: ^1.6.4
|
specifier: ^1.6.4
|
||||||
version: 1.6.4
|
version: 1.6.4
|
||||||
|
cors:
|
||||||
|
specifier: ^2.8.6
|
||||||
|
version: 2.8.6
|
||||||
did-jwt:
|
did-jwt:
|
||||||
specifier: ^7.4.7
|
specifier: ^7.4.7
|
||||||
version: 7.4.7
|
version: 7.4.7
|
||||||
@@ -33,6 +36,9 @@ importers:
|
|||||||
specifier: ^4.22.3
|
specifier: ^4.22.3
|
||||||
version: 4.22.3
|
version: 4.22.3
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
'@types/cors':
|
||||||
|
specifier: ^2.8.19
|
||||||
|
version: 2.8.19
|
||||||
'@types/express':
|
'@types/express':
|
||||||
specifier: ^5.0.6
|
specifier: ^5.0.6
|
||||||
version: 5.0.6
|
version: 5.0.6
|
||||||
@@ -382,6 +388,9 @@ packages:
|
|||||||
'@types/connect@3.4.38':
|
'@types/connect@3.4.38':
|
||||||
resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==}
|
resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==}
|
||||||
|
|
||||||
|
'@types/cors@2.8.19':
|
||||||
|
resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==}
|
||||||
|
|
||||||
'@types/express-serve-static-core@5.1.1':
|
'@types/express-serve-static-core@5.1.1':
|
||||||
resolution: {integrity: sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==}
|
resolution: {integrity: sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==}
|
||||||
|
|
||||||
@@ -530,6 +539,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
|
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
|
|
||||||
|
cors@2.8.6:
|
||||||
|
resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==}
|
||||||
|
engines: {node: '>= 0.10'}
|
||||||
|
|
||||||
data-uri-to-buffer@4.0.1:
|
data-uri-to-buffer@4.0.1:
|
||||||
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
|
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
|
||||||
engines: {node: '>= 12'}
|
engines: {node: '>= 12'}
|
||||||
@@ -926,6 +939,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==}
|
resolution: {integrity: sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
object-assign@4.1.1:
|
||||||
|
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
object-hash@3.0.0:
|
object-hash@3.0.0:
|
||||||
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
|
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
@@ -1480,6 +1497,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 22.19.19
|
'@types/node': 22.19.19
|
||||||
|
|
||||||
|
'@types/cors@2.8.19':
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 22.19.19
|
||||||
|
|
||||||
'@types/express-serve-static-core@5.1.1':
|
'@types/express-serve-static-core@5.1.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 22.19.19
|
'@types/node': 22.19.19
|
||||||
@@ -1657,6 +1678,11 @@ snapshots:
|
|||||||
|
|
||||||
cookie@0.7.2: {}
|
cookie@0.7.2: {}
|
||||||
|
|
||||||
|
cors@2.8.6:
|
||||||
|
dependencies:
|
||||||
|
object-assign: 4.1.1
|
||||||
|
vary: 1.1.2
|
||||||
|
|
||||||
data-uri-to-buffer@4.0.1: {}
|
data-uri-to-buffer@4.0.1: {}
|
||||||
|
|
||||||
debug@4.4.3:
|
debug@4.4.3:
|
||||||
@@ -2193,6 +2219,8 @@ snapshots:
|
|||||||
detect-libc: 2.1.2
|
detect-libc: 2.1.2
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
object-assign@4.1.1: {}
|
||||||
|
|
||||||
object-hash@3.0.0:
|
object-hash@3.0.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
|||||||
@@ -4,3 +4,8 @@ onlyBuiltDependencies:
|
|||||||
- cbor-extract
|
- cbor-extract
|
||||||
- esbuild
|
- esbuild
|
||||||
- protobufjs
|
- protobufjs
|
||||||
|
allowBuilds:
|
||||||
|
'@firebase/util': set this to true or false
|
||||||
|
cbor-extract: set this to true or false
|
||||||
|
esbuild: set this to true or false
|
||||||
|
protobufjs: set this to true or false
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import cors from "cors";
|
||||||
import express from "express";
|
import express from "express";
|
||||||
import "./services/firebase.js";
|
import "./services/firebase.js";
|
||||||
import { debugRouter } from "./routes/debug.js";
|
import { debugRouter } from "./routes/debug.js";
|
||||||
@@ -7,6 +8,14 @@ import { startScheduler } from "./scheduler.js";
|
|||||||
const app = express();
|
const app = express();
|
||||||
const port = Number(process.env.PORT) || 3000;
|
const port = Number(process.env.PORT) || 3000;
|
||||||
|
|
||||||
|
app.use(
|
||||||
|
cors({
|
||||||
|
origin: true,
|
||||||
|
methods: ["GET", "POST", "OPTIONS"],
|
||||||
|
allowedHeaders: ["Content-Type", "Authorization"],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
// Keep stable for diagnostics tooling compatibility
|
// Keep stable for diagnostics tooling compatibility
|
||||||
|
|||||||
@@ -1,16 +1,49 @@
|
|||||||
|
import type { NextFunction, Request, Response } from "express";
|
||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
import { db } from "../db/fcmTokens.js";
|
import { db } from "../db/fcmTokens.js";
|
||||||
import { requireAuth } from "../middleware/auth.js";
|
import { requireAuth } from "../middleware/auth.js";
|
||||||
import { errorMessage, formatElapsedMs } from "../util/formatElapsed.js";
|
import { errorMessage, formatElapsedMs } from "../util/formatElapsed.js";
|
||||||
import { maskToken } from "../util/maskToken.js";
|
import { maskToken } from "../util/maskToken.js";
|
||||||
|
|
||||||
|
/** Synthetic userId for unauthenticated local debug registrations (testMode). */
|
||||||
|
const LOCAL_TEST_USER_ID = "__notification_local_test__";
|
||||||
|
|
||||||
|
function isNotificationLocalTestBypass(req: Request): boolean {
|
||||||
|
if (req.headers.authorization?.startsWith("Bearer ")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const body = req.body;
|
||||||
|
return (
|
||||||
|
body !== null &&
|
||||||
|
typeof body === "object" &&
|
||||||
|
(body as { testMode?: unknown }).testMode === true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function requireAuthOrNotificationLocalTest(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
): Promise<void> {
|
||||||
|
if (isNotificationLocalTestBypass(req)) {
|
||||||
|
req.did = LOCAL_TEST_USER_ID;
|
||||||
|
console.log("[Auth] Local notification test bypass");
|
||||||
|
next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return requireAuth(req, res, next);
|
||||||
|
}
|
||||||
|
|
||||||
export const notificationsRouter = Router();
|
export const notificationsRouter = Router();
|
||||||
|
|
||||||
notificationsRouter.get("/", (_req, res) => {
|
notificationsRouter.get("/", (_req, res) => {
|
||||||
res.json({ ok: true, resource: "notifications" });
|
res.json({ ok: true, resource: "notifications" });
|
||||||
});
|
});
|
||||||
|
|
||||||
notificationsRouter.post("/refresh", requireAuth, async (req, res) => {
|
notificationsRouter.post(
|
||||||
|
"/refresh",
|
||||||
|
requireAuthOrNotificationLocalTest,
|
||||||
|
async (req, res) => {
|
||||||
const started = Date.now();
|
const started = Date.now();
|
||||||
const userId = req.did;
|
const userId = req.did;
|
||||||
if (userId === undefined) {
|
if (userId === undefined) {
|
||||||
@@ -26,7 +59,9 @@ notificationsRouter.post("/refresh", requireAuth, async (req, res) => {
|
|||||||
const canonicalDeviceId =
|
const canonicalDeviceId =
|
||||||
typeof deviceId === "string" ? deviceId.trim() : undefined;
|
typeof deviceId === "string" ? deviceId.trim() : undefined;
|
||||||
const token =
|
const token =
|
||||||
typeof fcmToken === "string" && fcmToken.length > 0 ? fcmToken : undefined;
|
typeof fcmToken === "string" && fcmToken.length > 0
|
||||||
|
? fcmToken
|
||||||
|
: undefined;
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
"[Refresh] Request received",
|
"[Refresh] Request received",
|
||||||
@@ -76,9 +111,13 @@ notificationsRouter.post("/refresh", requireAuth, async (req, res) => {
|
|||||||
"deviceId=" + device.deviceId + ",",
|
"deviceId=" + device.deviceId + ",",
|
||||||
"token suffix=" + maskToken(device.fcmToken)
|
"token suffix=" + maskToken(device.fcmToken)
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
notificationsRouter.post("/register", requireAuth, async (req, res) => {
|
notificationsRouter.post(
|
||||||
|
"/register",
|
||||||
|
requireAuthOrNotificationLocalTest,
|
||||||
|
async (req, res) => {
|
||||||
const started = Date.now();
|
const started = Date.now();
|
||||||
const userId = req.did;
|
const userId = req.did;
|
||||||
if (userId === undefined) {
|
if (userId === undefined) {
|
||||||
@@ -178,4 +217,5 @@ notificationsRouter.post("/register", requireAuth, async (req, res) => {
|
|||||||
);
|
);
|
||||||
res.sendStatus(500);
|
res.sendStatus(500);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user