import {Inject, Injectable, Maybe, Field, ORMUser, FieldType, Routing} from '@extollo/lib' import {Pub} from '../../pub/types' import {Certificate} from './pub/Certificate.model' import * as child_process from 'child_process' @Injectable() export class User extends ORMUser { @Inject() protected readonly routing!: Routing @Field(FieldType.varchar) public tagline?: string @Field(FieldType.varchar, 'photo_url') public photoUrl?: string get pubUrl(): string { return `${this.routing.getAppUrl().toRemote}/pub/${this.username}` } async toWebfinger(): Promise { const host = new URL(this.routing.getAppUrl().toRemote).host return { subject: `acct:${this.username}@${host}`, aliases: [], links: [ { rel: 'self', type: 'application/activity+json', href: this.pubUrl, }, { rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: `${this.pubUrl}/web`, }, ], } } async toPub(): Promise { return { "@context": [ "https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1" ], id: this.pubUrl, type: 'Person', name: `${this.firstName ? this.firstName + ' ' : ''}${this.lastName || ''}`.trim() || this.username, url: `${this.pubUrl}/web`, discoverable: true, indexable: false, published: '2023-11-06T00:00:00.000Z', // FIXME ...(this.tagline ? {summary: this.tagline} : {}), ...(this.photoUrl ? {icon: this.photoUrl} : {}), // image: '', // FIXME preferredUsername: this.username, manuallyApprovesFollowers: false, 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()) }) }) } }