feat: add delete alias functionality (fix #4) 👍
This commit is contained in:
parent
bec36602b5
commit
5b6fd15007
3 changed files with 48 additions and 4 deletions
|
@ -12,7 +12,7 @@
|
||||||
"@std/encoding": "jsr:@std/encoding@^1.0.5",
|
"@std/encoding": "jsr:@std/encoding@^1.0.5",
|
||||||
"nostr-tools": "jsr:@nostr/tools@^2.10.4",
|
"nostr-tools": "jsr:@nostr/tools@^2.10.4",
|
||||||
"@std/assert": "jsr:@std/assert@1",
|
"@std/assert": "jsr:@std/assert@1",
|
||||||
"@arx/utils": "https://git.arx-ccn.com/Arx/ts-utils/raw/commit/c1d309ba097ada64cd072ec1e3e97edaaf8773b6/src/index.ts",
|
"@arx/utils": "https://git.arx-ccn.com/Arx/ts-utils/raw/commit/d5e91a356d48016753f526930d4a50863641e8ce/src/index.ts",
|
||||||
"smtp-server": "npm:smtp-server@^3.13.6",
|
"smtp-server": "npm:smtp-server@^3.13.6",
|
||||||
"winston": "npm:winston@^3.17.0"
|
"winston": "npm:winston@^3.17.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -714,7 +714,12 @@
|
||||||
"https://git.arx-ccn.com/Arx/ts-utils/raw/commit/c1d309ba097ada64cd072ec1e3e97edaaf8773b6/src/email.ts": "ee77141a139894b10bbd0bc68338ebf1a6261a241b97732de547c791e6b0462c",
|
"https://git.arx-ccn.com/Arx/ts-utils/raw/commit/c1d309ba097ada64cd072ec1e3e97edaaf8773b6/src/email.ts": "ee77141a139894b10bbd0bc68338ebf1a6261a241b97732de547c791e6b0462c",
|
||||||
"https://git.arx-ccn.com/Arx/ts-utils/raw/commit/c1d309ba097ada64cd072ec1e3e97edaaf8773b6/src/general.ts": "692b4c44ec137cf7ef7128337f63a4a96ef8b09057beb7ec9940a6939a615bb4",
|
"https://git.arx-ccn.com/Arx/ts-utils/raw/commit/c1d309ba097ada64cd072ec1e3e97edaaf8773b6/src/general.ts": "692b4c44ec137cf7ef7128337f63a4a96ef8b09057beb7ec9940a6939a615bb4",
|
||||||
"https://git.arx-ccn.com/Arx/ts-utils/raw/commit/c1d309ba097ada64cd072ec1e3e97edaaf8773b6/src/index.ts": "fae9d057707d0632a2d82611e773a9627f199fc038cf823bfc4ecca0cfa0f064",
|
"https://git.arx-ccn.com/Arx/ts-utils/raw/commit/c1d309ba097ada64cd072ec1e3e97edaaf8773b6/src/index.ts": "fae9d057707d0632a2d82611e773a9627f199fc038cf823bfc4ecca0cfa0f064",
|
||||||
"https://git.arx-ccn.com/Arx/ts-utils/raw/commit/c1d309ba097ada64cd072ec1e3e97edaaf8773b6/src/nostr.ts": "c72faf0cb4a76a746f141965d366926868b8cbc36bec1b559f921481402521c4"
|
"https://git.arx-ccn.com/Arx/ts-utils/raw/commit/c1d309ba097ada64cd072ec1e3e97edaaf8773b6/src/nostr.ts": "c72faf0cb4a76a746f141965d366926868b8cbc36bec1b559f921481402521c4",
|
||||||
|
"https://git.arx-ccn.com/Arx/ts-utils/raw/commit/d5e91a356d48016753f526930d4a50863641e8ce/src/cashu.ts": "1e759c2a0095be1702d34cf6bdbe2408447329a6189bb111d04573a5e1d15bff",
|
||||||
|
"https://git.arx-ccn.com/Arx/ts-utils/raw/commit/d5e91a356d48016753f526930d4a50863641e8ce/src/email.ts": "ee77141a139894b10bbd0bc68338ebf1a6261a241b97732de547c791e6b0462c",
|
||||||
|
"https://git.arx-ccn.com/Arx/ts-utils/raw/commit/d5e91a356d48016753f526930d4a50863641e8ce/src/general.ts": "692b4c44ec137cf7ef7128337f63a4a96ef8b09057beb7ec9940a6939a615bb4",
|
||||||
|
"https://git.arx-ccn.com/Arx/ts-utils/raw/commit/d5e91a356d48016753f526930d4a50863641e8ce/src/index.ts": "fae9d057707d0632a2d82611e773a9627f199fc038cf823bfc4ecca0cfa0f064",
|
||||||
|
"https://git.arx-ccn.com/Arx/ts-utils/raw/commit/d5e91a356d48016753f526930d4a50863641e8ce/src/nostr.ts": "c72faf0cb4a76a746f141965d366926868b8cbc36bec1b559f921481402521c4"
|
||||||
},
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {npubToPubKeyString, pubKeyStringToNpub, TokenInfoWithMailSubscriptionDur
|
||||||
|
|
||||||
const NPUB_REGEX = /^npub1[023456789acdefghjklmnpqrstuvwxyz]{58}$/;
|
const NPUB_REGEX = /^npub1[023456789acdefghjklmnpqrstuvwxyz]{58}$/;
|
||||||
const CASHU_REGEX = /^cashu[A-Za-z0-9+-_]*={0,3}$/;
|
const CASHU_REGEX = /^cashu[A-Za-z0-9+-_]*={0,3}$/;
|
||||||
|
const ALIAS_REGEX = /^(?=.{4,32}$)[a-z][a-z0-9](?:[.\-_]?[a-z0-9]+)*$/;
|
||||||
|
|
||||||
export class HttpServer {
|
export class HttpServer {
|
||||||
private app: Hono;
|
private app: Hono;
|
||||||
|
@ -23,6 +24,7 @@ export class HttpServer {
|
||||||
.get("/aliases/:npub", this.getAliasesForNpub)
|
.get("/aliases/:npub", this.getAliasesForNpub)
|
||||||
.get("/alias/:alias", this.getNpubForAlias)
|
.get("/alias/:alias", this.getNpubForAlias)
|
||||||
.post("/addAlias", this.addAlias)
|
.post("/addAlias", this.addAlias)
|
||||||
|
.delete("/alias/:alias", this.deleteAlias)
|
||||||
.post("/addTime/:npub", this.addTimeToNpub);
|
.post("/addTime/:npub", this.addTimeToNpub);
|
||||||
|
|
||||||
Deno.serve({ port }, this.app.fetch);
|
Deno.serve({ port }, this.app.fetch);
|
||||||
|
@ -95,11 +97,47 @@ export class HttpServer {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
deleteAlias = async (c: HonoContext) => {
|
||||||
|
const alias = c.req.param("alias");
|
||||||
|
|
||||||
|
const unpacked = await this.getUnpackedAuthHeader(
|
||||||
|
c.req.header("Authorization"),
|
||||||
|
`/alias/${alias}`,
|
||||||
|
"DELETE",
|
||||||
|
);
|
||||||
|
const unpackedKeyToNpub = pubKeyStringToNpub(unpacked.pubkey);
|
||||||
|
|
||||||
|
const user = await getUserByNpub(this.db, unpackedKeyToNpub);
|
||||||
|
if (!user) {
|
||||||
|
return c.json({ error: "Unauthorized" }, 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user.aliases.includes(alias)) {
|
||||||
|
return c.json({ error: "Not found" }, 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.db.execute({
|
||||||
|
sql: `
|
||||||
|
DELETE FROM aliases
|
||||||
|
WHERE alias = $alias AND npub = $npub;
|
||||||
|
`,
|
||||||
|
args: { alias, npub: unpackedKeyToNpub },
|
||||||
|
});
|
||||||
|
|
||||||
|
return c.json({ success: true });
|
||||||
|
};
|
||||||
|
|
||||||
addAlias = async (c: HonoContext) => {
|
addAlias = async (c: HonoContext) => {
|
||||||
const { alias } = await c.req.json<{
|
let { alias } = await c.req.json<{
|
||||||
alias: string;
|
alias: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
alias = alias.trim();
|
||||||
|
|
||||||
|
if (!ALIAS_REGEX.test(alias)) {
|
||||||
|
return c.json({ error: "Invalid alias format" }, 400);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const unpacked = await this.getUnpackedAuthHeader(
|
const unpacked = await this.getUnpackedAuthHeader(
|
||||||
c.req.header("Authorization"),
|
c.req.header("Authorization"),
|
||||||
|
@ -223,6 +261,7 @@ export class HttpServer {
|
||||||
private getUnpackedAuthHeader = async (
|
private getUnpackedAuthHeader = async (
|
||||||
auth: string | undefined,
|
auth: string | undefined,
|
||||||
url: string,
|
url: string,
|
||||||
|
method: string = "POST",
|
||||||
) => {
|
) => {
|
||||||
if (!auth) {
|
if (!auth) {
|
||||||
throw new Error("Unauthorized");
|
throw new Error("Unauthorized");
|
||||||
|
@ -231,7 +270,7 @@ export class HttpServer {
|
||||||
const validate = await nip98.validateToken(
|
const validate = await nip98.validateToken(
|
||||||
authHeader,
|
authHeader,
|
||||||
`${Deno.env.get("PUBLIC_API_BASE_URL")!}${url}`,
|
`${Deno.env.get("PUBLIC_API_BASE_URL")!}${url}`,
|
||||||
"POST",
|
method,
|
||||||
);
|
);
|
||||||
if (!validate) {
|
if (!validate) {
|
||||||
throw new Error("Unauthorized");
|
throw new Error("Unauthorized");
|
||||||
|
|
Loading…
Reference in a new issue