Add author auth, forking, tags, and stats tracking
Introduce token-based author authentication (register/verify API), skill forking with EditGate protection, tag metadata on skills, and download/push stats. Enhanced push scripts with token auth and per-skill filtering. Updated UI with stats, tags, and author info on skill cards.
This commit is contained in:
55
dist/server/chunks/tokens_CAzj9Aj8.mjs
vendored
Normal file
55
dist/server/chunks/tokens_CAzj9Aj8.mjs
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import crypto from 'node:crypto';
|
||||
|
||||
const TOKENS_FILE = path.resolve(process.env.TOKENS_FILE || "data/tokens.json");
|
||||
async function readStore() {
|
||||
try {
|
||||
const raw = await fs.readFile(TOKENS_FILE, "utf-8");
|
||||
return JSON.parse(raw);
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
async function writeStore(store) {
|
||||
const dir = path.dirname(TOKENS_FILE);
|
||||
await fs.mkdir(dir, { recursive: true });
|
||||
const tmp = TOKENS_FILE + ".tmp";
|
||||
await fs.writeFile(tmp, JSON.stringify(store, null, 2), "utf-8");
|
||||
await fs.rename(tmp, TOKENS_FILE);
|
||||
}
|
||||
function hashToken(token) {
|
||||
return crypto.createHash("sha256").update(token).digest("hex");
|
||||
}
|
||||
async function generateToken(email, name) {
|
||||
const store = await readStore();
|
||||
if (store[email]) {
|
||||
throw new Error("Email already registered");
|
||||
}
|
||||
const token = crypto.randomBytes(32).toString("hex");
|
||||
store[email] = {
|
||||
hash: hashToken(token),
|
||||
name,
|
||||
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
||||
};
|
||||
await writeStore(store);
|
||||
return token;
|
||||
}
|
||||
async function verifyToken(email, token) {
|
||||
if (!email || !token) return false;
|
||||
const store = await readStore();
|
||||
const entry = store[email];
|
||||
if (!entry) return false;
|
||||
return entry.hash === hashToken(token);
|
||||
}
|
||||
async function hasToken(email) {
|
||||
const store = await readStore();
|
||||
return Boolean(store[email]);
|
||||
}
|
||||
function extractBearerToken(request) {
|
||||
const auth = request.headers.get("Authorization") || "";
|
||||
const match = auth.match(/^Bearer\s+(\S+)$/i);
|
||||
return match ? match[1] : "";
|
||||
}
|
||||
|
||||
export { extractBearerToken as e, generateToken as g, hasToken as h, verifyToken as v };
|
||||
Reference in New Issue
Block a user