summaryrefslogtreecommitdiff
path: root/src/server/api/private
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/api/private')
-rw-r--r--src/server/api/private/signup-pending.ts35
-rw-r--r--src/server/api/private/signup.ts62
2 files changed, 86 insertions, 11 deletions
diff --git a/src/server/api/private/signup-pending.ts b/src/server/api/private/signup-pending.ts
new file mode 100644
index 0000000000..c0638a1cda
--- /dev/null
+++ b/src/server/api/private/signup-pending.ts
@@ -0,0 +1,35 @@
+import * as Koa from 'koa';
+import { Users, UserPendings, UserProfiles } from '@/models/index';
+import { signup } from '../common/signup';
+import signin from '../common/signin';
+
+export default async (ctx: Koa.Context) => {
+ const body = ctx.request.body;
+
+ const code = body['code'];
+
+ try {
+ const pendingUser = await UserPendings.findOneOrFail({ code });
+
+ const { account, secret } = await signup({
+ username: pendingUser.username,
+ passwordHash: pendingUser.password,
+ });
+
+ UserPendings.delete({
+ id: pendingUser.id,
+ });
+
+ const profile = await UserProfiles.findOneOrFail(account.id);
+
+ await UserProfiles.update({ userId: profile.userId }, {
+ email: pendingUser.email,
+ emailVerified: true,
+ emailVerifyCode: null,
+ });
+
+ signin(ctx, account);
+ } catch (e) {
+ ctx.throw(400, e);
+ }
+};
diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts
index ef61767f65..93caaea935 100644
--- a/src/server/api/private/signup.ts
+++ b/src/server/api/private/signup.ts
@@ -1,8 +1,13 @@
import * as Koa from 'koa';
+import rndstr from 'rndstr';
+import * as bcrypt from 'bcryptjs';
import { fetchMeta } from '@/misc/fetch-meta';
import { verifyHcaptcha, verifyRecaptcha } from '@/misc/captcha';
-import { Users, RegistrationTickets } from '@/models/index';
+import { Users, RegistrationTickets, UserPendings } from '@/models/index';
import { signup } from '../common/signup';
+import config from '@/config';
+import { sendEmail } from '@/services/send-email';
+import { genId } from '@/misc/gen-id';
export default async (ctx: Koa.Context) => {
const body = ctx.request.body;
@@ -29,8 +34,16 @@ export default async (ctx: Koa.Context) => {
const password = body['password'];
const host: string | null = process.env.NODE_ENV === 'test' ? (body['host'] || null) : null;
const invitationCode = body['invitationCode'];
+ const emailAddress = body['emailAddress'];
- if (instance && instance.disableRegistration) {
+ if (instance.emailRequiredForSignup) {
+ if (emailAddress == null || typeof emailAddress != 'string') {
+ ctx.status = 400;
+ return;
+ }
+ }
+
+ if (instance.disableRegistration) {
if (invitationCode == null || typeof invitationCode != 'string') {
ctx.status = 400;
return;
@@ -48,18 +61,45 @@ export default async (ctx: Koa.Context) => {
RegistrationTickets.delete(ticket.id);
}
- try {
- const { account, secret } = await signup(username, password, host);
+ if (instance.emailRequiredForSignup) {
+ const code = rndstr('a-z0-9', 16);
+
+ // Generate hash of password
+ const salt = await bcrypt.genSalt(8);
+ const hash = await bcrypt.hash(password, salt);
- const res = await Users.pack(account, account, {
- detail: true,
- includeSecrets: true
+ await UserPendings.insert({
+ id: genId(),
+ createdAt: new Date(),
+ code,
+ email: emailAddress,
+ username: username,
+ password: hash,
});
- (res as any).token = secret;
+ const link = `${config.url}/signup-complete/${code}`;
+
+ sendEmail(emailAddress, 'Signup',
+ `To complete signup, please click this link:<br><a href="${link}">${link}</a>`,
+ `To complete signup, please click this link: ${link}`);
- ctx.body = res;
- } catch (e) {
- ctx.throw(400, e);
+ ctx.status = 204;
+ } else {
+ try {
+ const { account, secret } = await signup({
+ username, password, host
+ });
+
+ const res = await Users.pack(account, account, {
+ detail: true,
+ includeSecrets: true
+ });
+
+ (res as any).token = secret;
+
+ ctx.body = res;
+ } catch (e) {
+ ctx.throw(400, e);
+ }
}
};