You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
3.1 KiB

import {Inject, Injectable, Maybe, ModelBuilder, ORMUser, Related, 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
get pubUrl(): string {
return `${this.routing.getAppUrl().toRemote}/pub/${this.username}`
}
async toWebfinger(): Promise<Pub.Webfinger> {
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<Pub.Actor> {
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
// icon: '', // FIXME
// 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<Maybe<Certificate>> {
return Certificate.query<Certificate>()
.where('reltype', '=', 'user')
.where('relid', '=', this.userId)
.first()
}
async getCertificate(): Promise<Certificate> {
const existing = await this.certificate()
if ( existing ) {
return existing
}
const certificate = this.make<Certificate>(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<string> {
return new Promise<string>((res, rej) => {
child_process.exec(cmd, (err, stdout, stderr) => {
if ( err ) {
return rej(err)
}
res(stdout.trim())
})
})
}
}