Add lookups for static user list, make LDAP optional
This commit is contained in:
parent
ba7336b4ee
commit
28520c59b9
18
config.ts
18
config.ts
@ -1,12 +1,28 @@
|
|||||||
import { load } from "@std/dotenv";
|
import { load } from "@std/dotenv";
|
||||||
|
import { parse } from "jsr:@std/yaml";
|
||||||
|
import { log } from "./log.ts";
|
||||||
|
|
||||||
const dirname = new URL(".", import.meta.url).pathname;
|
const dirname = new URL(".", import.meta.url).pathname;
|
||||||
await load({ envPath: `${dirname}/.env`, export: true });
|
await load({ envPath: `${dirname}/.env`, export: true });
|
||||||
|
|
||||||
|
let staticUsers;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const yamlContent = await Deno.readTextFile(`${dirname}/users.yaml`);
|
||||||
|
staticUsers = parse(yamlContent);
|
||||||
|
log("Static user config:", "blue");
|
||||||
|
log(Deno.inspect(staticUsers), "blue");
|
||||||
|
} catch {
|
||||||
|
staticUsers = {};
|
||||||
|
log(`Could not find or parse a "users.yaml" config`, "yellow");
|
||||||
|
}
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
port: Deno.env.get("PORT") || 8000,
|
port: Deno.env.get("PORT") || 8000,
|
||||||
base_url: Deno.env.get("BASE_URL") || `http://localhost:8000`,
|
base_url: Deno.env.get("BASE_URL") || `http://localhost:8000`,
|
||||||
home_relay_url: Deno.env.get("HOME_RELAY_URL") || "",
|
home_relay_url: Deno.env.get("HOME_RELAY_URL") || "",
|
||||||
|
staticUsers: staticUsers,
|
||||||
|
ldapEnabled: !!Deno.env.get("LDAP_URL"),
|
||||||
ldap: {
|
ldap: {
|
||||||
url: Deno.env.get("LDAP_URL"),
|
url: Deno.env.get("LDAP_URL"),
|
||||||
bindDN: Deno.env.get("LDAP_BIND_DN"),
|
bindDN: Deno.env.get("LDAP_BIND_DN"),
|
||||||
@ -15,4 +31,6 @@ const config = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
log(`LDAP enabled: ${config.ldapEnabled}`, "blue");
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
"@std/dotenv": "jsr:@std/dotenv@^0.225.2",
|
"@std/dotenv": "jsr:@std/dotenv@^0.225.2",
|
||||||
"@std/expect": "jsr:@std/expect@^1.0.5",
|
"@std/expect": "jsr:@std/expect@^1.0.5",
|
||||||
"@std/testing": "jsr:@std/testing@^1.0.3",
|
"@std/testing": "jsr:@std/testing@^1.0.3",
|
||||||
|
"@std/yaml": "jsr:@std/yaml@^1.0.5",
|
||||||
"ldapts": "npm:ldapts@^7.2.1"
|
"ldapts": "npm:ldapts@^7.2.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
deno.lock
generated
6
deno.lock
generated
@ -27,6 +27,8 @@
|
|||||||
"jsr:@std/path@1": "1.0.6",
|
"jsr:@std/path@1": "1.0.6",
|
||||||
"jsr:@std/path@^1.0.6": "1.0.6",
|
"jsr:@std/path@^1.0.6": "1.0.6",
|
||||||
"jsr:@std/testing@^1.0.3": "1.0.3",
|
"jsr:@std/testing@^1.0.3": "1.0.3",
|
||||||
|
"jsr:@std/yaml@*": "1.0.5",
|
||||||
|
"jsr:@std/yaml@^1.0.5": "1.0.5",
|
||||||
"npm:@noble/ciphers@~0.5.1": "0.5.3",
|
"npm:@noble/ciphers@~0.5.1": "0.5.3",
|
||||||
"npm:@noble/curves@1.2.0": "1.2.0",
|
"npm:@noble/curves@1.2.0": "1.2.0",
|
||||||
"npm:@noble/hashes@1.3.1": "1.3.1",
|
"npm:@noble/hashes@1.3.1": "1.3.1",
|
||||||
@ -186,6 +188,9 @@
|
|||||||
"jsr:@std/internal",
|
"jsr:@std/internal",
|
||||||
"jsr:@std/path@^1.0.6"
|
"jsr:@std/path@^1.0.6"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"@std/yaml@1.0.5": {
|
||||||
|
"integrity": "71ba3d334305ee2149391931508b2c293a8490f94a337eef3a09cade1a2a2742"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npm": {
|
"npm": {
|
||||||
@ -490,6 +495,7 @@
|
|||||||
"jsr:@std/dotenv@~0.225.2",
|
"jsr:@std/dotenv@~0.225.2",
|
||||||
"jsr:@std/expect@^1.0.5",
|
"jsr:@std/expect@^1.0.5",
|
||||||
"jsr:@std/testing@^1.0.3",
|
"jsr:@std/testing@^1.0.3",
|
||||||
|
"jsr:@std/yaml@^1.0.5",
|
||||||
"npm:ldapts@^7.2.1"
|
"npm:ldapts@^7.2.1"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
33
directory.ts
Normal file
33
directory.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import config from "./config.ts";
|
||||||
|
import { lookupUsernameByPubkey as ldapLookupUsername } from "./ldap.ts";
|
||||||
|
import { lookupPubkeyByUsername as ldapLookupPubkey } from "./ldap.ts";
|
||||||
|
|
||||||
|
export function lookupUsernameByPubkey(pubkey: string) {
|
||||||
|
let username;
|
||||||
|
for (const [key, value] of Object.entries(config.staticUsers)) {
|
||||||
|
if (value === pubkey) {
|
||||||
|
username = key;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (username) {
|
||||||
|
return username;
|
||||||
|
} else {
|
||||||
|
if (config.ldapEnabled) {
|
||||||
|
return ldapLookupUsername(pubkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function lookupPubkeyByUsername(username: string) {
|
||||||
|
const pubkey = config.staticUsers[username];
|
||||||
|
|
||||||
|
if (pubkey) {
|
||||||
|
return pubkey;
|
||||||
|
} else {
|
||||||
|
if (config.ldapEnabled) {
|
||||||
|
return ldapLookupPubkey(username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import { Context } 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 { lookupUsernameByPubkey } from "../ldap.ts";
|
import { lookupUsernameByPubkey } from "../directory.ts";
|
||||||
import notFoundHandler from "../handlers/not-found.ts";
|
import notFoundHandler from "../handlers/not-found.ts";
|
||||||
|
|
||||||
const naddrHandler = async function (ctx: Context) {
|
const naddrHandler = async function (ctx: Context) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Context } 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 { lookupUsernameByPubkey } from "../ldap.ts";
|
import { lookupUsernameByPubkey } from "../directory.ts";
|
||||||
import notFoundHandler from "../handlers/not-found.ts";
|
import notFoundHandler from "../handlers/not-found.ts";
|
||||||
|
|
||||||
const nprofileHandler = async function (ctx: Context) {
|
const nprofileHandler = async function (ctx: Context) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Context } 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 { lookupUsernameByPubkey } from "../ldap.ts";
|
import { lookupUsernameByPubkey } from "../directory.ts";
|
||||||
import notFoundHandler from "../handlers/not-found.ts";
|
import notFoundHandler from "../handlers/not-found.ts";
|
||||||
|
|
||||||
const npubHandler = async function (ctx: Context) {
|
const npubHandler = async function (ctx: Context) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Context } from "@oak/oak";
|
import { Context } from "@oak/oak";
|
||||||
import { log } from "../log.ts";
|
import { log } from "../log.ts";
|
||||||
import { lookupPubkeyByUsername } from "../ldap.ts";
|
import { lookupPubkeyByUsername } from "../directory.ts";
|
||||||
import { fetchArticlesByAuthor, fetchProfileEvent } from "../nostr.ts";
|
import { fetchArticlesByAuthor, fetchProfileEvent } from "../nostr.ts";
|
||||||
import { profileAtomFeed } from "../feeds.ts";
|
import { profileAtomFeed } from "../feeds.ts";
|
||||||
import Article from "../models/article.ts";
|
import Article from "../models/article.ts";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Context } from "@oak/oak";
|
import { Context } from "@oak/oak";
|
||||||
import { log } from "../log.ts";
|
import { log } from "../log.ts";
|
||||||
import { lookupPubkeyByUsername } from "../ldap.ts";
|
import { lookupPubkeyByUsername } from "../directory.ts";
|
||||||
import { fetchProfileEvent, fetchReplaceableEvent } from "../nostr.ts";
|
import { fetchProfileEvent, fetchReplaceableEvent } from "../nostr.ts";
|
||||||
import Article from "../models/article.ts";
|
import Article from "../models/article.ts";
|
||||||
import Profile from "../models/profile.ts";
|
import Profile from "../models/profile.ts";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Context } from "@oak/oak";
|
import { Context } from "@oak/oak";
|
||||||
import { log } from "../log.ts";
|
import { log } from "../log.ts";
|
||||||
import { lookupPubkeyByUsername } from "../ldap.ts";
|
import { lookupPubkeyByUsername } from "../directory.ts";
|
||||||
import { fetchArticlesByAuthor, fetchProfileEvent } from "../nostr.ts";
|
import { fetchArticlesByAuthor, fetchProfileEvent } from "../nostr.ts";
|
||||||
import Article from "../models/article.ts";
|
import Article from "../models/article.ts";
|
||||||
import Profile from "../models/profile.ts";
|
import Profile from "../models/profile.ts";
|
||||||
@ -27,6 +27,7 @@ const userProfileHandler = async function (ctx: Context) {
|
|||||||
|
|
||||||
ctx.response.body = html;
|
ctx.response.body = html;
|
||||||
} else {
|
} else {
|
||||||
|
log(`No profile event found for @${username}`, "yellow");
|
||||||
notFoundHandler(ctx);
|
notFoundHandler(ctx);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
8
ldap.ts
8
ldap.ts
@ -2,8 +2,12 @@ import { Client } from "ldapts";
|
|||||||
import { log } from "./log.ts";
|
import { log } from "./log.ts";
|
||||||
import config from "./config.ts";
|
import config from "./config.ts";
|
||||||
|
|
||||||
const { ldap } = config;
|
const { ldap, ldapEnabled } = config;
|
||||||
const client = new Client({ url: ldap.url });
|
|
||||||
|
let client;
|
||||||
|
if (ldapEnabled) {
|
||||||
|
client = new Client({ url: ldap.url });
|
||||||
|
}
|
||||||
|
|
||||||
export async function lookupPubkeyByUsername(username: string) {
|
export async function lookupPubkeyByUsername(username: string) {
|
||||||
let pubkey;
|
let pubkey;
|
||||||
|
@ -25,7 +25,8 @@ export default class Profile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get name(): string {
|
get name(): string {
|
||||||
return this.data.name || "Anonymous";
|
return this.data.display_name || this.data.displayName ||
|
||||||
|
this.data.name || "Anonymous";
|
||||||
}
|
}
|
||||||
|
|
||||||
get about(): string {
|
get about(): string {
|
||||||
|
2
users.yaml
Normal file
2
users.yaml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
_: b3e1b7c0ef48294bd856203bfd460625de95d3afb894e5f09b14cd1f0e7097cf
|
||||||
|
accounts: b3e1b7c1660b7db0ecb93ec55c09e67961171a5c4e9e2602f1b47477ea61c50a
|
Loading…
x
Reference in New Issue
Block a user