import {Maybe, ModelBuilder, ORMUser, Related} from '@extollo/lib' import {Pub} from '../../pub/types' import {Certificate} from './pub/Certificate.model' import * as child_process from 'child_process' export class User extends ORMUser { get pubUrl(): string { return `https://garrettmills.dev/pub/${this.username}` } async toWebfinger(): Promise { return { subject: `acct:${this.username}@garrettmills.dev`, // fixme links: [ { rel: 'self', type: 'application/activity+json', href: this.pubUrl, }, ], } } async toPub(): Promise { return { "@context": [ "https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1" ], id: this.pubUrl, type: 'Person', preferredUsername: this.username, inbox: `${this.pubUrl}/inbox`, publicKey: { id: `${this.pubUrl}#main-key`, owner: this.pubUrl, publicKeyPem: await this.getCertificate().then(c => c.pubkey), }, } } certificate(): Promise> { return Certificate.query() .where('reltype', '=', 'user') .where('relid', '=', this.userId) .first() } async getCertificate(): Promise { const existing = await this.certificate() if ( existing ) { return existing } const certificate = this.make(Certificate) certificate.reltype = 'user' certificate.relid = this.userId certificate.privkey = await this.exec('openssl genrsa -out - 2048') certificate.pubkey = await this.exec(`echo "${certificate.privkey}" | openssl rsa -outform PEM -pubout -out -`) await certificate.save() return certificate } /** Dirty, dirty, dirty. @fixme */ private async exec(cmd: string): Promise { return new Promise((res, rej) => { child_process.exec(cmd, (err, stdout, stderr) => { if ( err ) { return rej(err) } res(stdout.trim()) }) }) } }