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
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())
|
|
})
|
|
})
|
|
}
|
|
}
|