mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
Destroy everything
This commit is contained in:
parent
ee7864da8c
commit
5a2b1b7de7
4 changed files with 37 additions and 126 deletions
|
|
@ -81,7 +81,7 @@ import { hostMetaController } from '@/controllers/well-known/host-meta.ts';
|
||||||
import { nodeInfoController, nodeInfoSchemaController } from '@/controllers/well-known/nodeinfo.ts';
|
import { nodeInfoController, nodeInfoSchemaController } from '@/controllers/well-known/nodeinfo.ts';
|
||||||
import { nostrController } from '@/controllers/well-known/nostr.ts';
|
import { nostrController } from '@/controllers/well-known/nostr.ts';
|
||||||
import { webfingerController } from '@/controllers/well-known/webfinger.ts';
|
import { webfingerController } from '@/controllers/well-known/webfinger.ts';
|
||||||
import { auth19, requirePubkey } from '@/middleware/auth19.ts';
|
import { requirePubkey } from '@/middleware/auth19.ts';
|
||||||
import { auth98, requireProof, requireRole } from '@/middleware/auth98.ts';
|
import { auth98, requireProof, requireRole } from '@/middleware/auth98.ts';
|
||||||
import { cache } from '@/middleware/cache.ts';
|
import { cache } from '@/middleware/cache.ts';
|
||||||
import { csp } from '@/middleware/csp.ts';
|
import { csp } from '@/middleware/csp.ts';
|
||||||
|
|
@ -94,10 +94,6 @@ interface AppEnv extends HonoEnv {
|
||||||
Variables: {
|
Variables: {
|
||||||
/** Signer to get the logged-in user's pubkey, relays, and to sign events, or `undefined` if the user isn't logged in. */
|
/** Signer to get the logged-in user's pubkey, relays, and to sign events, or `undefined` if the user isn't logged in. */
|
||||||
signer?: NostrSigner;
|
signer?: NostrSigner;
|
||||||
/** Hex pubkey for the current user. If provided, the user is considered "logged in." */
|
|
||||||
pubkey?: string;
|
|
||||||
/** Hex secret key for the current user. Optional, but easiest way to use legacy Mastodon apps. */
|
|
||||||
seckey?: Uint8Array;
|
|
||||||
/** NIP-98 signed event proving the pubkey is owned by the user. */
|
/** NIP-98 signed event proving the pubkey is owned by the user. */
|
||||||
proof?: NostrEvent;
|
proof?: NostrEvent;
|
||||||
/** User associated with the pubkey, if any. */
|
/** User associated with the pubkey, if any. */
|
||||||
|
|
@ -130,7 +126,6 @@ app.use(
|
||||||
'*',
|
'*',
|
||||||
csp(),
|
csp(),
|
||||||
cors({ origin: '*', exposeHeaders: ['link'] }),
|
cors({ origin: '*', exposeHeaders: ['link'] }),
|
||||||
auth19,
|
|
||||||
auth98(),
|
auth98(),
|
||||||
storeMiddleware,
|
storeMiddleware,
|
||||||
signerMiddleware,
|
signerMiddleware,
|
||||||
|
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
import { HTTPException } from 'hono';
|
|
||||||
import { getPublicKey, nip19 } from 'nostr-tools';
|
|
||||||
|
|
||||||
import { type AppMiddleware } from '@/app.ts';
|
|
||||||
|
|
||||||
/** We only accept "Bearer" type. */
|
|
||||||
const BEARER_REGEX = new RegExp(`^Bearer (${nip19.BECH32_REGEX.source})$`);
|
|
||||||
|
|
||||||
/** NIP-19 auth middleware. */
|
|
||||||
const auth19: AppMiddleware = async (c, next) => {
|
|
||||||
const authHeader = c.req.header('authorization');
|
|
||||||
const match = authHeader?.match(BEARER_REGEX);
|
|
||||||
|
|
||||||
if (match) {
|
|
||||||
const [_, bech32] = match;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const decoded = nip19.decode(bech32!);
|
|
||||||
|
|
||||||
switch (decoded.type) {
|
|
||||||
case 'npub':
|
|
||||||
c.set('pubkey', decoded.data);
|
|
||||||
break;
|
|
||||||
case 'nprofile':
|
|
||||||
c.set('pubkey', decoded.data.pubkey);
|
|
||||||
break;
|
|
||||||
case 'nsec':
|
|
||||||
c.set('pubkey', getPublicKey(decoded.data));
|
|
||||||
c.set('seckey', decoded.data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (_e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await next();
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Throw a 401 if the pubkey isn't set. */
|
|
||||||
const requirePubkey: AppMiddleware = async (c, next) => {
|
|
||||||
if (!c.get('pubkey')) {
|
|
||||||
throw new HTTPException(401, { message: 'No pubkey provided' });
|
|
||||||
}
|
|
||||||
|
|
||||||
await next();
|
|
||||||
};
|
|
||||||
|
|
||||||
export { auth19, requirePubkey };
|
|
||||||
|
|
@ -1,12 +1,43 @@
|
||||||
|
import { NConnectSigner, NSecSigner } from '@nostrify/nostrify';
|
||||||
|
import { nip19 } from 'nostr-tools';
|
||||||
|
|
||||||
import { AppMiddleware } from '@/app.ts';
|
import { AppMiddleware } from '@/app.ts';
|
||||||
import { APISigner } from '@/signers/APISigner.ts';
|
import { AdminSigner } from '@/signers/AdminSigner.ts';
|
||||||
|
import { Storages } from '@/storages.ts';
|
||||||
|
|
||||||
|
/** We only accept "Bearer" type. */
|
||||||
|
const BEARER_REGEX = new RegExp(`^Bearer (${nip19.BECH32_REGEX.source})$`);
|
||||||
|
|
||||||
/** Make a `signer` object available to all controllers, or unset if the user isn't logged in. */
|
/** Make a `signer` object available to all controllers, or unset if the user isn't logged in. */
|
||||||
export const signerMiddleware: AppMiddleware = async (c, next) => {
|
export const signerMiddleware: AppMiddleware = async (c, next) => {
|
||||||
|
const header = c.req.header('authorization');
|
||||||
|
const match = header?.match(BEARER_REGEX);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
const [_, bech32] = match;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
c.set('signer', new APISigner(c));
|
const decoded = nip19.decode(bech32!);
|
||||||
|
|
||||||
|
switch (decoded.type) {
|
||||||
|
case 'npub':
|
||||||
|
c.set(
|
||||||
|
'signer',
|
||||||
|
new NConnectSigner({
|
||||||
|
pubkey: decoded.data,
|
||||||
|
relay: Storages.pubsub,
|
||||||
|
signer: new AdminSigner(),
|
||||||
|
timeout: 60000,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'nsec':
|
||||||
|
c.set('signer', new NSecSigner(decoded.data));
|
||||||
|
break;
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// do nothing
|
// the user is not logged in
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await next();
|
await next();
|
||||||
|
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
// deno-lint-ignore-file require-await
|
|
||||||
|
|
||||||
import { NConnectSigner, NostrEvent, NostrSigner, NSecSigner } from '@nostrify/nostrify';
|
|
||||||
import { HTTPException } from 'hono';
|
|
||||||
|
|
||||||
import { type AppContext } from '@/app.ts';
|
|
||||||
import { AdminSigner } from '@/signers/AdminSigner.ts';
|
|
||||||
import { Storages } from '@/storages.ts';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sign Nostr event using the app context.
|
|
||||||
*
|
|
||||||
* - If a secret key is provided, it will be used to sign the event.
|
|
||||||
* - Otherwise, it will use NIP-46 to sign the event.
|
|
||||||
*/
|
|
||||||
export class APISigner implements NostrSigner {
|
|
||||||
private signer: NostrSigner;
|
|
||||||
|
|
||||||
constructor(c: AppContext) {
|
|
||||||
const seckey = c.get('seckey');
|
|
||||||
const pubkey = c.get('pubkey');
|
|
||||||
|
|
||||||
if (!pubkey) {
|
|
||||||
throw new HTTPException(401, { message: 'Missing pubkey' });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (seckey) {
|
|
||||||
this.signer = new NSecSigner(seckey);
|
|
||||||
} else {
|
|
||||||
this.signer = new NConnectSigner({
|
|
||||||
pubkey,
|
|
||||||
relay: Storages.pubsub,
|
|
||||||
signer: new AdminSigner(),
|
|
||||||
timeout: 60000,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async getPublicKey(): Promise<string> {
|
|
||||||
return this.signer.getPublicKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
async signEvent(event: Omit<NostrEvent, 'id' | 'pubkey' | 'sig'>): Promise<NostrEvent> {
|
|
||||||
return this.signer.signEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly nip04 = {
|
|
||||||
encrypt: async (pubkey: string, plaintext: string): Promise<string> => {
|
|
||||||
return this.signer.nip04!.encrypt(pubkey, plaintext);
|
|
||||||
},
|
|
||||||
|
|
||||||
decrypt: async (pubkey: string, ciphertext: string): Promise<string> => {
|
|
||||||
return this.signer.nip04!.decrypt(pubkey, ciphertext);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
readonly nip44 = {
|
|
||||||
encrypt: async (pubkey: string, plaintext: string): Promise<string> => {
|
|
||||||
return this.signer.nip44!.encrypt(pubkey, plaintext);
|
|
||||||
},
|
|
||||||
|
|
||||||
decrypt: async (pubkey: string, ciphertext: string): Promise<string> => {
|
|
||||||
return this.signer.nip44!.decrypt(pubkey, ciphertext);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Loading…
Add table
Reference in a new issue