This commit is contained in:
Danny Morabito 2024-12-02 18:26:49 +01:00
parent ebec73a666
commit 0eba3efe24
Signed by: dannym
GPG key ID: 7CC8056A5A04557E
4 changed files with 28 additions and 5 deletions

View file

@ -3,4 +3,5 @@ DB_URL=file:./users.db
SMTP_PORT=6587
HTTP_PORT=3000
LOG_FILE=/tmp/nostr-email.log
PUBLIC_API_BASE_URL=https://api.npub.email
PUBLIC_API_BASE_URL=https://api.npub.email
MASTER_NSEC=nsec1...

View file

@ -11,6 +11,8 @@ if (!process.env.DB_URL)
throw new Error("DB_URL is not set");
if (!process.env.PUBLIC_API_BASE_URL)
throw new Error("PUBLIC_API_BASE_URL is not set");
if (!process.env.MASTER_NSEC)
throw new Error("MASTER_NSEC is not set");
const dbClient = createLibSQLClient({
url: process.env.DB_URL,

View file

@ -1,6 +1,5 @@
import {SMTPServer} from "smtp-server";
import {getNDK} from "./utils";
import {generateSecretKey} from "nostr-tools";
import {deriveNsecForEmail, getNDK} from "./utils";
import {NDKEvent, NDKKind, NDKPrivateKeySigner} from "@nostr-dev-kit/ndk";
import {PrismaClient} from "@prisma/client";
import {logger} from "./utils/logs";
@ -55,8 +54,10 @@ export class NostrSmtpServer {
continue;
}
const recipient = user.npub;
const randomKey = generateSecretKey();
const randomKeySinger = new NDKPrivateKeySigner(randomKey);
const randomKeySinger = new NDKPrivateKeySigner(deriveNsecForEmail(
process.env.MASTER_NSEC!,
session.envelope.mailFrom?.address
));
const ndk = getNDK();
ndk.signer = randomKeySinger;
await ndk.connect();

View file

@ -1,4 +1,5 @@
import NDK from "@nostr-dev-kit/ndk";
import * as crypto from "node:crypto";
export * from "./logs";
@ -14,3 +15,21 @@ export function getNDK() {
enableOutboxModel: true,
});
}
/**
* Derive a nostr private key from a master private key and an email address.
*
* This is done by taking the SHA-256 hash of the email address, and then taking
* the SHA-256 hash of the master private key concatenated with the email hash.
* The resulting hash is the nostr private key.
*
* @param masterNsec - The master nostr private key.
* @param email - The email address.
* @returns The nostr private key derived from the master key and email address as a uint8array.
*/
export function deriveNsecForEmail(masterNsec: string, email: string): Uint8Array {
const masterNsecHash = crypto.createHash('sha256').update(masterNsec).digest('hex');
const emailHash = crypto.createHash('sha256').update(email).digest('hex');
const sharedSecret = crypto.createHash('sha256').update(masterNsecHash + emailHash).digest('hex');
return Uint8Array.from(Buffer.from(sharedSecret, 'hex'));
}