summaryrefslogtreecommitdiff
path: root/src/server/api/endpoints/request-reset-password.ts
blob: f9928c2ee66030c1a94140a77e820d276eed0fdf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import $ from 'cafy';
import { publishMainStream } from '@/services/stream';
import define from '../define';
import rndstr from 'rndstr';
import config from '@/config/index';
import * as ms from 'ms';
import { Users, UserProfiles, PasswordResetRequests } from '@/models/index';
import { sendEmail } from '@/services/send-email';
import { ApiError } from '../error';
import { genId } from '@/misc/gen-id';
import { IsNull } from 'typeorm';

export const meta = {
	requireCredential: false as const,

	limit: {
		duration: ms('1hour'),
		max: 3
	},

	params: {
		username: {
			validator: $.str
		},

		email: {
			validator: $.str
		},
	},

	errors: {

	}
};

export default define(meta, async (ps) => {
	const user = await Users.findOne({
		usernameLower: ps.username.toLowerCase(),
		host: IsNull()
	});

	// 合致するユーザーが登録されていなかったら無視
	if (user == null) {
		return;
	}

	const profile = await UserProfiles.findOneOrFail(user.id);

	// 合致するメアドが登録されていなかったら無視
	if (profile.email !== ps.email) {
		return;
	}

	// メアドが認証されていなかったら無視
	if (!profile.emailVerified) {
		return;
	}

	const token = rndstr('a-z0-9', 64);

	await PasswordResetRequests.insert({
		id: genId(),
		createdAt: new Date(),
		userId: profile.userId,
		token
	});

	const link = `${config.url}/reset-password/${token}`;

	sendEmail(ps.email, 'Password reset requested',
		`To reset password, please click this link:<br><a href="${link}">${link}</a>`,
		`To reset password, please click this link: ${link}`);
});