misskey/packages/backend/src/core/CreateSystemUserService.ts

87 lines
2.3 KiB
TypeScript
Raw Normal View History

/*
2024-02-12 03:37:45 +01:00
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { randomUUID } from 'node:crypto';
2022-09-17 20:27:08 +02:00
import { Inject, Injectable } from '@nestjs/common';
import bcrypt from 'bcryptjs';
import { IsNull, DataSource } from 'typeorm';
import { genRsaKeyPair } from '@/misc/gen-key-pair.js';
import { MiUser } from '@/models/User.js';
import { MiUserProfile } from '@/models/UserProfile.js';
2022-09-17 20:27:08 +02:00
import { IdService } from '@/core/IdService.js';
import { MiUserKeypair } from '@/models/UserKeypair.js';
import { MiUsedUsername } from '@/models/UsedUsername.js';
2022-09-17 20:27:08 +02:00
import { DI } from '@/di-symbols.js';
import generateNativeUserToken from '@/misc/generate-native-user-token.js';
import { bindThis } from '@/decorators.js';
2022-09-17 20:27:08 +02:00
@Injectable()
export class CreateSystemUserService {
constructor(
@Inject(DI.db)
private db: DataSource,
private idService: IdService,
) {
}
@bindThis
public async createSystemUser(username: string): Promise<MiUser> {
const password = randomUUID();
2022-09-17 20:27:08 +02:00
// Generate hash of password
const salt = await bcrypt.genSalt(8);
const hash = await bcrypt.hash(password, salt);
2022-09-17 20:27:08 +02:00
// Generate secret
const secret = generateNativeUserToken();
2023-07-21 04:59:00 +02:00
const keyPair = await genRsaKeyPair();
let account!: MiUser;
2022-09-17 20:27:08 +02:00
// Start transaction
await this.db.transaction(async transactionalEntityManager => {
const exist = await transactionalEntityManager.findOneBy(MiUser, {
2022-09-17 20:27:08 +02:00
usernameLower: username.toLowerCase(),
host: IsNull(),
});
2022-09-17 20:27:08 +02:00
if (exist) throw new Error('the user is already exists');
account = await transactionalEntityManager.insert(MiUser, {
id: this.idService.gen(),
2022-09-17 20:27:08 +02:00
username: username,
usernameLower: username.toLowerCase(),
host: null,
token: secret,
isRoot: false,
2022-09-17 20:27:08 +02:00
isLocked: true,
isExplorable: false,
isBot: true,
}).then(x => transactionalEntityManager.findOneByOrFail(MiUser, x.identifiers[0]));
await transactionalEntityManager.insert(MiUserKeypair, {
2022-09-17 20:27:08 +02:00
publicKey: keyPair.publicKey,
privateKey: keyPair.privateKey,
userId: account.id,
});
await transactionalEntityManager.insert(MiUserProfile, {
2022-09-17 20:27:08 +02:00
userId: account.id,
autoAcceptFollowed: false,
password: hash,
});
await transactionalEntityManager.insert(MiUsedUsername, {
2022-09-17 20:27:08 +02:00
createdAt: new Date(),
username: username.toLowerCase(),
});
});
2022-09-17 20:27:08 +02:00
return account;
}
}