WIP Resolve username via npub, LDAP
This commit is contained in:
parent
b618c6a1a1
commit
9a19f7249c
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.env
|
@ -1,12 +1,14 @@
|
|||||||
{
|
{
|
||||||
"tasks": {
|
"tasks": {
|
||||||
"dev": "deno run --allow-net --deny-env --watch main.ts"
|
"dev": "deno run --allow-net --allow-read --allow-env --deny-env --watch main.ts"
|
||||||
},
|
},
|
||||||
"imports": {
|
"imports": {
|
||||||
"@deno/gfm": "jsr:@deno/gfm@^0.9.0",
|
"@deno/gfm": "jsr:@deno/gfm@^0.9.0",
|
||||||
"@nostr/tools": "jsr:@nostr/tools@^2.3.1",
|
"@nostr/tools": "jsr:@nostr/tools@^2.3.1",
|
||||||
"@nostrify/nostrify": "jsr:@nostrify/nostrify@^0.36.1",
|
"@nostrify/nostrify": "jsr:@nostrify/nostrify@^0.36.1",
|
||||||
"@oak/oak": "jsr:@oak/oak@^17.1.0",
|
"@oak/oak": "jsr:@oak/oak@^17.1.0",
|
||||||
"@std/assert": "jsr:@std/assert@1"
|
"@std/assert": "jsr:@std/assert@1",
|
||||||
|
"@std/dotenv": "jsr:@std/dotenv@^0.225.2",
|
||||||
|
"ldapts": "npm:ldapts@^7.2.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
78
deno.lock
generated
78
deno.lock
generated
@ -12,6 +12,7 @@
|
|||||||
"jsr:@std/bytes@1": "1.0.2",
|
"jsr:@std/bytes@1": "1.0.2",
|
||||||
"jsr:@std/bytes@^1.0.2": "1.0.2",
|
"jsr:@std/bytes@^1.0.2": "1.0.2",
|
||||||
"jsr:@std/crypto@1": "1.0.3",
|
"jsr:@std/crypto@1": "1.0.3",
|
||||||
|
"jsr:@std/dotenv@~0.225.2": "0.225.2",
|
||||||
"jsr:@std/encoding@1": "1.0.5",
|
"jsr:@std/encoding@1": "1.0.5",
|
||||||
"jsr:@std/encoding@^1.0.5": "1.0.5",
|
"jsr:@std/encoding@^1.0.5": "1.0.5",
|
||||||
"jsr:@std/encoding@~0.224.1": "0.224.3",
|
"jsr:@std/encoding@~0.224.1": "0.224.3",
|
||||||
@ -29,6 +30,7 @@
|
|||||||
"npm:github-slugger@2": "2.0.0",
|
"npm:github-slugger@2": "2.0.0",
|
||||||
"npm:he@^1.2.0": "1.2.0",
|
"npm:he@^1.2.0": "1.2.0",
|
||||||
"npm:katex@0.16": "0.16.11",
|
"npm:katex@0.16": "0.16.11",
|
||||||
|
"npm:ldapts@^7.2.1": "7.2.1",
|
||||||
"npm:lru-cache@^10.2.0": "10.2.2",
|
"npm:lru-cache@^10.2.0": "10.2.2",
|
||||||
"npm:marked-alert@2": "2.1.0_marked@12.0.2",
|
"npm:marked-alert@2": "2.1.0_marked@12.0.2",
|
||||||
"npm:marked-footnote@^1.2.0": "1.2.4_marked@12.0.2",
|
"npm:marked-footnote@^1.2.0": "1.2.4_marked@12.0.2",
|
||||||
@ -123,6 +125,9 @@
|
|||||||
"@std/crypto@1.0.3": {
|
"@std/crypto@1.0.3": {
|
||||||
"integrity": "a2a32f51ddef632d299e3879cd027c630dcd4d1d9a5285d6e6788072f4e51e7f"
|
"integrity": "a2a32f51ddef632d299e3879cd027c630dcd4d1d9a5285d6e6788072f4e51e7f"
|
||||||
},
|
},
|
||||||
|
"@std/dotenv@0.225.2": {
|
||||||
|
"integrity": "e2025dce4de6c7bca21dece8baddd4262b09d5187217e231b033e088e0c4dd23"
|
||||||
|
},
|
||||||
"@std/encoding@0.224.3": {
|
"@std/encoding@0.224.3": {
|
||||||
"integrity": "5e861b6d81be5359fad4155e591acf17c0207b595112d1840998bb9f476dbdaf"
|
"integrity": "5e861b6d81be5359fad4155e591acf17c0207b595112d1840998bb9f476dbdaf"
|
||||||
},
|
},
|
||||||
@ -218,9 +223,33 @@
|
|||||||
"@scure/base@1.1.7"
|
"@scure/base@1.1.7"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"@types/asn1@0.2.4": {
|
||||||
|
"integrity": "sha512-V91DSJ2l0h0gRhVP4oBfBzRBN9lAbPUkGDMCnwedqPKX2d84aAMc9CulOvxdw1f7DfEYx99afab+Rsm3e52jhA==",
|
||||||
|
"dependencies": [
|
||||||
|
"@types/node"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@types/node@22.5.4": {
|
||||||
|
"integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==",
|
||||||
|
"dependencies": [
|
||||||
|
"undici-types"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"asn1@0.2.6": {
|
||||||
|
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
|
||||||
|
"dependencies": [
|
||||||
|
"safer-buffer"
|
||||||
|
]
|
||||||
|
},
|
||||||
"commander@8.3.0": {
|
"commander@8.3.0": {
|
||||||
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="
|
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="
|
||||||
},
|
},
|
||||||
|
"debug@4.3.7": {
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"dependencies": [
|
||||||
|
"ms"
|
||||||
|
]
|
||||||
|
},
|
||||||
"deepmerge@4.3.1": {
|
"deepmerge@4.3.1": {
|
||||||
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="
|
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="
|
||||||
},
|
},
|
||||||
@ -279,6 +308,17 @@
|
|||||||
"commander"
|
"commander"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ldapts@7.2.1": {
|
||||||
|
"integrity": "sha512-2NSA9drjHdRiApF+TO18c+Hy/uyBLs96OS6Gia4+dPQWPxvqDbu3Ji2beCbNCXTvvgxDj4cLZ0WoOZLt5ojfAg==",
|
||||||
|
"dependencies": [
|
||||||
|
"@types/asn1",
|
||||||
|
"asn1",
|
||||||
|
"debug",
|
||||||
|
"strict-event-emitter-types",
|
||||||
|
"uuid",
|
||||||
|
"whatwg-url"
|
||||||
|
]
|
||||||
|
},
|
||||||
"lru-cache@10.2.2": {
|
"lru-cache@10.2.2": {
|
||||||
"integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ=="
|
"integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ=="
|
||||||
},
|
},
|
||||||
@ -304,6 +344,9 @@
|
|||||||
"marked@12.0.2": {
|
"marked@12.0.2": {
|
||||||
"integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q=="
|
"integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q=="
|
||||||
},
|
},
|
||||||
|
"ms@2.1.3": {
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
|
},
|
||||||
"nanoid@3.3.7": {
|
"nanoid@3.3.7": {
|
||||||
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="
|
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="
|
||||||
},
|
},
|
||||||
@ -342,6 +385,12 @@
|
|||||||
"prismjs@1.29.0": {
|
"prismjs@1.29.0": {
|
||||||
"integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q=="
|
"integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q=="
|
||||||
},
|
},
|
||||||
|
"punycode@2.3.1": {
|
||||||
|
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="
|
||||||
|
},
|
||||||
|
"safer-buffer@2.1.2": {
|
||||||
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||||
|
},
|
||||||
"sanitize-html@2.13.1": {
|
"sanitize-html@2.13.1": {
|
||||||
"integrity": "sha512-ZXtKq89oue4RP7abL9wp/9URJcqQNABB5GGJ2acW1sdO8JTVl92f4ygD7Yc9Ze09VAZhnt2zegeU0tbNsdcLYg==",
|
"integrity": "sha512-ZXtKq89oue4RP7abL9wp/9URJcqQNABB5GGJ2acW1sdO8JTVl92f4ygD7Yc9Ze09VAZhnt2zegeU0tbNsdcLYg==",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
@ -356,9 +405,34 @@
|
|||||||
"source-map-js@1.2.1": {
|
"source-map-js@1.2.1": {
|
||||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="
|
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="
|
||||||
},
|
},
|
||||||
|
"strict-event-emitter-types@2.0.0": {
|
||||||
|
"integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA=="
|
||||||
|
},
|
||||||
|
"tr46@5.0.0": {
|
||||||
|
"integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==",
|
||||||
|
"dependencies": [
|
||||||
|
"punycode"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"undici-types@6.19.8": {
|
||||||
|
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="
|
||||||
|
},
|
||||||
|
"uuid@10.0.0": {
|
||||||
|
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="
|
||||||
|
},
|
||||||
|
"webidl-conversions@7.0.0": {
|
||||||
|
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="
|
||||||
|
},
|
||||||
"websocket-ts@2.1.5": {
|
"websocket-ts@2.1.5": {
|
||||||
"integrity": "sha512-rCNl9w6Hsir1azFm/pbjBEFzLD/gi7Th5ZgOxMifB6STUfTSovYAzryWw0TRvSZ1+Qu1Z5Plw4z42UfTNA9idA=="
|
"integrity": "sha512-rCNl9w6Hsir1azFm/pbjBEFzLD/gi7Th5ZgOxMifB6STUfTSovYAzryWw0TRvSZ1+Qu1Z5Plw4z42UfTNA9idA=="
|
||||||
},
|
},
|
||||||
|
"whatwg-url@14.0.0": {
|
||||||
|
"integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==",
|
||||||
|
"dependencies": [
|
||||||
|
"tr46",
|
||||||
|
"webidl-conversions"
|
||||||
|
]
|
||||||
|
},
|
||||||
"zod@3.23.8": {
|
"zod@3.23.8": {
|
||||||
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g=="
|
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g=="
|
||||||
}
|
}
|
||||||
@ -381,7 +455,9 @@
|
|||||||
"jsr:@nostr/tools@^2.3.1",
|
"jsr:@nostr/tools@^2.3.1",
|
||||||
"jsr:@nostrify/nostrify@~0.36.1",
|
"jsr:@nostrify/nostrify@~0.36.1",
|
||||||
"jsr:@oak/oak@^17.1.0",
|
"jsr:@oak/oak@^17.1.0",
|
||||||
"jsr:@std/assert@1"
|
"jsr:@std/assert@1",
|
||||||
|
"jsr:@std/dotenv@~0.225.2",
|
||||||
|
"npm:ldapts@^7.2.1"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ctx } from "@oak/oak";
|
import { Context } from "@oak/oak";
|
||||||
import { nip19 } from "@nostr/tools";
|
import { nip19 } from "@nostr/tools";
|
||||||
import { log } from "../log.ts";
|
import { log } from "../log.ts";
|
||||||
import { articleHtml } from "../html.ts"
|
import { articleHtml } from "../html.ts"
|
||||||
@ -7,12 +7,12 @@ import {
|
|||||||
fetchProfileEvent
|
fetchProfileEvent
|
||||||
} from "../nostr.ts";
|
} from "../nostr.ts";
|
||||||
|
|
||||||
const naddrHandler = async function (ctx: ctx) {
|
const naddrHandler = async function (ctx: Context) {
|
||||||
const { request } = ctx;
|
const { request } = ctx;
|
||||||
const { path } = ctx.params;
|
const naddr = ctx.params.path;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const r = nip19.decode(path);
|
const r = nip19.decode(naddr);
|
||||||
const articleEvent = await fetchReplaceableEvent(r.data.pubkey, r.data.identifier);
|
const articleEvent = await fetchReplaceableEvent(r.data.pubkey, r.data.identifier);
|
||||||
const profileEvent = await fetchProfileEvent(r.data.pubkey);
|
const profileEvent = await fetchProfileEvent(r.data.pubkey);
|
||||||
let profile;
|
let profile;
|
||||||
|
@ -1,10 +1,30 @@
|
|||||||
import { Context } from "@oak/oak";
|
import { Context } from "@oak/oak";
|
||||||
|
import { nip19 } from "@nostr/tools";
|
||||||
|
import { log } from "../log.ts";
|
||||||
|
import { fetchProfileEvent } from "../nostr.ts";
|
||||||
|
import { profilePageHtml } from "../html.ts"
|
||||||
|
|
||||||
const nprofileHandler = function (context: Context) {
|
const nprofileHandler = async function (ctx: Context) {
|
||||||
const { request, response } = context;
|
const { request } = ctx;
|
||||||
const fullPath = request.url.pathname;
|
const nprofile = ctx.params.path;
|
||||||
|
|
||||||
response.body = `You are viewing an nprofile with address: ${fullPath}`;
|
try {
|
||||||
|
const r = nip19.decode(nprofile);
|
||||||
|
const profileEvent = await fetchProfileEvent(r.data.pubkey);
|
||||||
|
|
||||||
|
if (profileEvent) {
|
||||||
|
const html = profilePageHtml(profileEvent);
|
||||||
|
|
||||||
|
ctx.response.body = html;
|
||||||
|
} else {
|
||||||
|
ctx.response.status = 404;
|
||||||
|
ctx.response.body = "Not Found";
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log(e, "yellow");
|
||||||
|
ctx.response.status = 404;
|
||||||
|
ctx.response.body = "Not Found";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nprofileHandler;
|
export default nprofileHandler;
|
||||||
|
30
handlers/npub.ts
Normal file
30
handlers/npub.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { Context } from "@oak/oak";
|
||||||
|
import { nip19 } from "@nostr/tools";
|
||||||
|
import { log } from "../log.ts";
|
||||||
|
import { fetchProfileEvent } from "../nostr.ts";
|
||||||
|
import { profilePageHtml } from "../html.ts"
|
||||||
|
|
||||||
|
const npubHandler = async function (ctx: Context) {
|
||||||
|
const { request } = ctx;
|
||||||
|
const npub = ctx.params.path;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const r = nip19.decode(npub);
|
||||||
|
const profileEvent = await fetchProfileEvent(r.data);
|
||||||
|
|
||||||
|
if (profileEvent) {
|
||||||
|
const html = profilePageHtml(profileEvent);
|
||||||
|
|
||||||
|
ctx.response.body = html;
|
||||||
|
} else {
|
||||||
|
ctx.response.status = 404;
|
||||||
|
ctx.response.body = "Not Found";
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log(e, "yellow");
|
||||||
|
ctx.response.status = 404;
|
||||||
|
ctx.response.body = "Not Found";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default npubHandler;
|
31
handlers/username.ts
Normal file
31
handlers/username.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { Context } from "@oak/oak";
|
||||||
|
import { nip19 } from "@nostr/tools";
|
||||||
|
import { log } from "../log.ts";
|
||||||
|
import { lookupPubkeyByUsername } from "../ldap.ts";
|
||||||
|
import { fetchProfileEvent } from "../nostr.ts";
|
||||||
|
import { profilePageHtml } from "../html.ts"
|
||||||
|
|
||||||
|
const usernameHandler = async function (ctx: Context) {
|
||||||
|
const { request } = ctx;
|
||||||
|
const username = ctx.params.path.replace(/^@/, '');;
|
||||||
|
const pubkey = await lookupPubkeyByUsername(username);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const profileEvent = await fetchProfileEvent(pubkey);
|
||||||
|
|
||||||
|
if (profileEvent) {
|
||||||
|
const html = profilePageHtml(profileEvent);
|
||||||
|
|
||||||
|
ctx.response.body = html;
|
||||||
|
} else {
|
||||||
|
ctx.response.status = 404;
|
||||||
|
ctx.response.body = "Not Found";
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log(e, "yellow");
|
||||||
|
ctx.response.status = 404;
|
||||||
|
ctx.response.body = "Not Found";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default usernameHandler;
|
34
html.ts
34
html.ts
@ -31,6 +31,11 @@ export function htmlLayout(title: string, body: string) {
|
|||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.profile-page img.avatar {
|
||||||
|
height: 128px;
|
||||||
|
width: 128px;
|
||||||
|
}
|
||||||
|
|
||||||
a.anchor {
|
a.anchor {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -143,3 +148,32 @@ export function articleHtml(articleEvent: object, profile: object) {
|
|||||||
|
|
||||||
return htmlLayout(title, body);
|
return htmlLayout(title, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function profilePageHtml(profileEvent: object) {
|
||||||
|
const profile = JSON.parse(profileEvent.content);
|
||||||
|
const name = profile.name || "Anonymous";
|
||||||
|
const title = `${name} on Nostr`
|
||||||
|
// const date = new Date(articleEvent.created_at * 1000);
|
||||||
|
// const formattedDate = date.toLocaleDateString("en-US", {
|
||||||
|
// year: "numeric",
|
||||||
|
// month: "long",
|
||||||
|
// day: "numeric",
|
||||||
|
// });
|
||||||
|
|
||||||
|
const body = `
|
||||||
|
<main class="profile-page">
|
||||||
|
<header>
|
||||||
|
<img class="avatar" src="${profile.picture}" alt="User Avatar" />
|
||||||
|
<div class="bio">
|
||||||
|
<h1>${profile.name}</h1>
|
||||||
|
<p class="about">
|
||||||
|
${profile.about}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<h2>Articles</h2>
|
||||||
|
</main>
|
||||||
|
`;
|
||||||
|
|
||||||
|
return htmlLayout(title, body);
|
||||||
|
}
|
||||||
|
35
ldap.ts
Normal file
35
ldap.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { load } from "@std/dotenv";
|
||||||
|
import { Client } from 'ldapts';
|
||||||
|
import { log } from "./log.ts";
|
||||||
|
|
||||||
|
const dirname = new URL('.', import.meta.url).pathname;
|
||||||
|
await load({ envPath: `${dirname}/.env`, export: true });
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
url: Deno.env.get("LDAP_URL"),
|
||||||
|
bindDN: Deno.env.get("LDAP_BIND_DN"),
|
||||||
|
password: Deno.env.get("LDAP_PASSWORD"),
|
||||||
|
searchDN: Deno.env.get("LDAP_SEARCH_DN")
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = new Client({ url: config.url });
|
||||||
|
|
||||||
|
export async function lookupPubkeyByUsername (username) {
|
||||||
|
let pubkey;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await client.bind(config.bindDN, config.password);
|
||||||
|
|
||||||
|
const { searchEntries } = await client.search(config.searchDN, {
|
||||||
|
filter: `(cn=${username})`,
|
||||||
|
attributes: ['nostrKey']
|
||||||
|
});
|
||||||
|
|
||||||
|
pubkey = searchEntries[0]?.nostrKey;
|
||||||
|
} catch (ex) {
|
||||||
|
log(ex, "red");
|
||||||
|
} finally {
|
||||||
|
await client.unbind();
|
||||||
|
return pubkey;
|
||||||
|
}
|
||||||
|
}
|
10
main.ts
10
main.ts
@ -2,16 +2,22 @@ import { Application, Router } from "@oak/oak";
|
|||||||
import { log } from "./log.ts";
|
import { log } from "./log.ts";
|
||||||
import naddrHandler from "./handlers/naddr.ts";
|
import naddrHandler from "./handlers/naddr.ts";
|
||||||
import nprofileHandler from "./handlers/nprofile.ts";
|
import nprofileHandler from "./handlers/nprofile.ts";
|
||||||
|
import npubHandler from "./handlers/npub.ts";
|
||||||
|
import usernameHandler from "./handlers/username.ts";
|
||||||
|
|
||||||
const router = new Router();
|
const router = new Router();
|
||||||
|
|
||||||
router.get("/:path", async (ctx: ctx) => {
|
router.get("/:path", async (ctx: ctx) => {
|
||||||
const { path } = ctx.params;
|
const { path } = ctx.params;
|
||||||
|
|
||||||
if (path && path.startsWith("naddr")) {
|
if (path.startsWith("naddr")) {
|
||||||
await naddrHandler(ctx);
|
await naddrHandler(ctx);
|
||||||
} else if (prefix && prefix.startsWith("nprofile")) {
|
} else if (path.startsWith("nprofile")) {
|
||||||
await nprofileHandler(ctx);
|
await nprofileHandler(ctx);
|
||||||
|
} else if (path.startsWith("npub")) {
|
||||||
|
await npubHandler(ctx);
|
||||||
|
} else if (path.startsWith("@")) {
|
||||||
|
await usernameHandler(ctx);
|
||||||
} else {
|
} else {
|
||||||
ctx.response.status = 404;
|
ctx.response.status = 404;
|
||||||
ctx.response.body = "Not Found";
|
ctx.response.body = "Not Found";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user