import { getConfig, getHost } from "@config"; import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn, } from "typeorm"; import { APIAccount } from "~types/entities/account"; const config = getConfig(); /** * Stores local and remote users */ @Entity({ name: "users", }) export class User extends BaseEntity { @PrimaryGeneratedColumn("uuid") id!: string; @Column("varchar", { unique: true, }) username!: string; @Column("varchar", { unique: true, }) display_name!: string; @Column("varchar") password!: string; @Column("varchar", { unique: true, }) email!: string; @Column("varchar", { default: "", }) bio!: string; @CreateDateColumn() created_at!: Date; @UpdateDateColumn() updated_at!: Date; @Column("varchar") public_key!: string; @Column("varchar") private_key!: string; async generateKeys(): Promise { // openssl genrsa -out private.pem 2048 // openssl rsa -in private.pem -outform PEM -pubout -out public.pem const keys = await crypto.subtle.generateKey( { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256", modulusLength: 4096, publicExponent: new Uint8Array([0x01, 0x00, 0x01]), }, true, ["sign", "verify"] ); const privateKey = btoa( String.fromCharCode.apply(null, [ ...new Uint8Array( await crypto.subtle.exportKey("pkcs8", keys.privateKey) ), ]) ); const publicKey = btoa( String.fromCharCode( ...new Uint8Array( await crypto.subtle.exportKey("spki", keys.publicKey) ) ) ); // Add header, footer and newlines later on // These keys are PEM encrypted this.private_key = privateKey; this.public_key = publicKey; } // eslint-disable-next-line @typescript-eslint/require-await async toAPI(): Promise { return { acct: `@${this.username}@${getHost()}`, avatar: "", avatar_static: "", bot: false, created_at: this.created_at.toISOString(), display_name: "", followers_count: 0, following_count: 0, group: false, header: "", header_static: "", id: this.id, locked: false, moved: null, noindex: false, note: this.bio, suspended: false, url: `${config.http.base_url}/@${this.username}`, username: this.username, emojis: [], fields: [], limited: false, source: undefined, statuses_count: 0, discoverable: undefined, role: undefined, mute_expires_at: undefined, }; } }