mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
注册功能
This commit is contained in:
1 parent
f259106aa3
commit
6e28dd868e
8 files changed
+55
-39
No files matched your search
@@ -122,6 +122,9 @@ MIDDLEWARE(async (ctx, next) => {
|
|||||||
ctx.response.type = 'application/octet-stream';
|
ctx.response.type = 'application/octet-stream';
|
||||||
ctx.redirect(ctx.setRedirect);
|
ctx.redirect(ctx.setRedirect);
|
||||||
}
|
}
|
||||||
|
} else if (ctx.setRedirect) {
|
||||||
|
ctx.response.type = 'application/octet-stream';
|
||||||
|
ctx.redirect(ctx.setRedirect);
|
||||||
} else {
|
} else {
|
||||||
throw new NotFoundError();
|
throw new NotFoundError();
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-24
@@ -37,37 +37,43 @@ POST('/logout', requirePerm(PERM_LOGGEDIN), async ctx => {
|
|||||||
ctx.session = { uid: 1 };
|
ctx.session = { uid: 1 };
|
||||||
ctx.body = {};
|
ctx.body = {};
|
||||||
});
|
});
|
||||||
GET('/register/:code', requirePerm(PERM_REGISTER_USER), async ctx => {
|
GET('/register', requirePerm(PERM_REGISTER_USER), async ctx => {
|
||||||
let code = ctx.request.body.code;
|
ctx.templateName = 'user_register.html';
|
||||||
let { mail } = await token.get(code, token.TYPE_REGISTRATION);
|
|
||||||
if (!mail) throw new InvalidTokenError(token.TYPE_REGISTRATION, code);
|
|
||||||
ctx.body = { mail };
|
|
||||||
});
|
});
|
||||||
GET('/register/:code', requirePerm(PERM_REGISTER_USER), async ctx => {
|
GET('/register/:code', requirePerm(PERM_REGISTER_USER), async ctx => {
|
||||||
let { code, password, verify_password, uname } = ctx.request.body;
|
ctx.templateName = 'user_register_with_code.html';
|
||||||
let { mail } = await token.get(code, token.TYPE_REGISTRATION);
|
let code = ctx.params.code;
|
||||||
if (!mail) throw new InvalidTokenError(token.TYPE_REGISTRATION, code);
|
let { email } = await token.get(code, token.TYPE_REGISTRATION);
|
||||||
|
if (!email) throw new InvalidTokenError(token.TYPE_REGISTRATION, code);
|
||||||
|
ctx.body = { email };
|
||||||
|
});
|
||||||
|
POST('/register/:code', requirePerm(PERM_REGISTER_USER), async ctx => {
|
||||||
|
let code = ctx.params.code;
|
||||||
|
let { password, verify_password, uname } = ctx.request.body;
|
||||||
|
let { email } = await token.get(code, token.TYPE_REGISTRATION);
|
||||||
|
if (!email) throw new InvalidTokenError(token.TYPE_REGISTRATION, code);
|
||||||
if (password != verify_password) throw new VerifyPasswordError();
|
if (password != verify_password) throw new VerifyPasswordError();
|
||||||
let uid = await system.incUserCounter();
|
let uid = await system.incUserCounter();
|
||||||
await user.add(uid, uname, password, mail, ctx.remote_ip);
|
await user.create({ uid, uname, password, email, regip: ctx.request.ip });
|
||||||
await token.delete(code, token.TYPE_REGISTRATION);
|
await token.delete(code, token.TYPE_REGISTRATION);
|
||||||
ctx.session.uid = uid;
|
ctx.session.uid = uid;
|
||||||
ctx.body = {};
|
ctx.body = {};
|
||||||
|
ctx.setRedirect = '/';
|
||||||
});
|
});
|
||||||
|
|
||||||
if (options.smtp.user) {
|
if (options.smtp.user) {
|
||||||
POST('/register', requirePerm(PERM_REGISTER_USER), limitRate('send_mail', 3600, 30), async ctx => {
|
POST('/register', requirePerm(PERM_REGISTER_USER), limitRate('send_mail', 3600, 30), async ctx => {
|
||||||
let email = ctx.request.body.email;
|
let email = ctx.request.body.mail;
|
||||||
validator.check_mail(email);
|
validator.checkEmail(email);
|
||||||
if (await user.get_by_mail(email)) throw new UserAlreadyExistError(email);
|
if (await user.getByEmail(email, true)) throw new UserAlreadyExistError(email);
|
||||||
let rid = await token.add(token.TYPE_REGISTRATION, options.registration_token_expire_seconds, { mail: email });
|
let rid = await token.add(token.TYPE_REGISTRATION, options.registration_token_expire_seconds, { email });
|
||||||
let m = await ctx.render('user_register_mail', { url: `/register/${rid}` }, true);
|
let m = await ctx.render('user_register_mail', { url: `/register/${rid}` }, true);
|
||||||
await mail.send_mail(email, 'Sign Up', 'user_register_mail', m);
|
await mail.sendMail(email, 'Sign Up', 'user_register_mail', m);
|
||||||
ctx.body = {};
|
ctx.body = {};
|
||||||
});
|
});
|
||||||
POST('/lostpass', limitRate('send_mail', 3600, 30), async ctx => {
|
POST('/lostpass', limitRate('send_mail', 3600, 30), async ctx => {
|
||||||
let email = ctx.request.body.mail;
|
let email = ctx.request.body.mail;
|
||||||
validator.check_mail(email);
|
validator.checkEmail(email);
|
||||||
let udoc = await user.getByEmail(email);
|
let udoc = await user.getByEmail(email);
|
||||||
if (!udoc) throw new UserNotFoundError(email);
|
if (!udoc) throw new UserNotFoundError(email);
|
||||||
let tid = await token.add(
|
let tid = await token.add(
|
||||||
@@ -76,7 +82,7 @@ if (options.smtp.user) {
|
|||||||
{ uid: udoc._id }
|
{ uid: udoc._id }
|
||||||
);
|
);
|
||||||
let m = await ctx.render('user_lostpass_mail', { url: `/lostpass/${tid}`, uname: udoc.uname }, true);
|
let m = await ctx.render('user_lostpass_mail', { url: `/lostpass/${tid}`, uname: udoc.uname }, true);
|
||||||
await mail.send_mail(email, 'Lost Password', 'user_lostpass_mail', m);
|
await mail.sendMail(email, 'Lost Password', 'user_lostpass_mail', m);
|
||||||
ctx.body = {};
|
ctx.body = {};
|
||||||
});
|
});
|
||||||
GET('/lostpass/:code', async ctx => {
|
GET('/lostpass/:code', async ctx => {
|
||||||
@@ -93,19 +99,18 @@ if (options.smtp.user) {
|
|||||||
let tdoc = await token.get(code, token.TYPE_LOSTPASS);
|
let tdoc = await token.get(code, token.TYPE_LOSTPASS);
|
||||||
if (!tdoc) throw new InvalidTokenError(token.TYPE_LOSTPASS, code);
|
if (!tdoc) throw new InvalidTokenError(token.TYPE_LOSTPASS, code);
|
||||||
if (password != verify_password) throw new VerifyPasswordError();
|
if (password != verify_password) throw new VerifyPasswordError();
|
||||||
await user.set_password(tdoc.uid, password);
|
await user.setPassword(tdoc.uid, password);
|
||||||
await token.delete(code, token.TYPE_LOSTPASS);
|
await token.delete(code, token.TYPE_LOSTPASS);
|
||||||
ctx.redirect('/');
|
ctx.redirect('/');
|
||||||
});
|
});
|
||||||
} else
|
} else
|
||||||
POST('/register', requirePerm(PERM_REGISTER_USER), async ctx => {
|
POST('/register', requirePerm(PERM_REGISTER_USER), limitRate('send_mail', 3600, 60), async ctx => {
|
||||||
let email = ctx.request.body.email;
|
let email = ctx.request.body.mail;
|
||||||
validator.check_mail(email);
|
validator.checkEmail(email);
|
||||||
if (await user.get_by_mail(email)) throw new UserAlreadyExistError(email);
|
if (await user.getByEmail(email, true)) throw new UserAlreadyExistError(email);
|
||||||
let token = await token.add(token.TYPE_REGISTRATION, options.registration_token_expire_seconds, { mail: email });
|
let t = await token.add(token.TYPE_REGISTRATION, options.session.registration_token_expire_seconds, { email });
|
||||||
ctx.body = { token };
|
ctx.setRedirect = `/register/${t[0]}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
@app.route('/user/{uid:-?\d+}', 'user_detail')
|
@app.route('/user/{uid:-?\d+}', 'user_detail')
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ module.exports = {
|
|||||||
let begin_at = new Date(cur_time - cur_time % (period_secs * 1000));
|
let begin_at = new Date(cur_time - cur_time % (period_secs * 1000));
|
||||||
let expire_at = new Date(begin_at.getTime() + period_secs * 1000);
|
let expire_at = new Date(begin_at.getTime() + period_secs * 1000);
|
||||||
try {
|
try {
|
||||||
await coll.find_one_and_update({
|
await coll.findOneAndUpdate({
|
||||||
ident, begin_at, expire_at,
|
ident, begin_at, expire_at,
|
||||||
op: { $not: { $gte: max_operations } }
|
op: { $not: { $gte: max_operations } }
|
||||||
}, { $inc: { op: 1 } }, { upsert: true });
|
}, { $inc: { op: 1 } }, { upsert: true });
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ module.exports = {
|
|||||||
* @param {number} tokenType type of the token.
|
* @param {number} tokenType type of the token.
|
||||||
* @param {number} expireSeconds expire time, in seconds.
|
* @param {number} expireSeconds expire time, in seconds.
|
||||||
* @param {object} data extra data.
|
* @param {object} data extra data.
|
||||||
* @returns {string} token ID
|
* @returns {Array} token ID, token data
|
||||||
*/
|
*/
|
||||||
async add(tokenType, expireSeconds, data) {
|
async add(tokenType, expireSeconds, data) {
|
||||||
let now = new Date();
|
let now = new Date();
|
||||||
@@ -62,7 +62,7 @@ module.exports = {
|
|||||||
* @returns {boolean} true if deleted, or false.
|
* @returns {boolean} true if deleted, or false.
|
||||||
*/
|
*/
|
||||||
async delete(tokenId, tokenType) {
|
async delete(tokenId, tokenType) {
|
||||||
let result = await coll.delete_one({ _id: tokenId, tokenType });
|
let result = await coll.deleteOne({ _id: tokenId, tokenType });
|
||||||
return !!result.deletedCount;
|
return !!result.deletedCount;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
+15
-10
@@ -1,8 +1,9 @@
|
|||||||
const
|
const
|
||||||
{ UserNotFoundError, UserAlreadyExistError } = require('../error'),
|
|
||||||
system = require('./system'),
|
system = require('./system'),
|
||||||
{ pwhash, validator } = require('../utils'),
|
{ UserNotFoundError, UserAlreadyExistError } = require('../error'),
|
||||||
db = require('../service/db.js'),
|
{ pwhash } = require('../utils'),
|
||||||
|
validator = require('../lib/validator'),
|
||||||
|
db = require('../service/db'),
|
||||||
coll = db.collection('user'),
|
coll = db.collection('user'),
|
||||||
coll_role = db.collection('role');
|
coll_role = db.collection('role');
|
||||||
|
|
||||||
@@ -40,10 +41,13 @@ async function getByUname(uname) {
|
|||||||
udoc.perm = role.perm;
|
udoc.perm = role.perm;
|
||||||
return new USER(udoc);
|
return new USER(udoc);
|
||||||
}
|
}
|
||||||
async function getByEmail(email) {
|
async function getByEmail(email, ignoreMissing = false) {
|
||||||
let emailLower = email.trim().toLowerCase();
|
let emailLower = email.trim().toLowerCase();
|
||||||
let udoc = await coll.findOne({ emailLower });
|
let udoc = await coll.findOne({ emailLower });
|
||||||
if (!udoc) throw new UserNotFoundError(email);
|
if (!udoc) {
|
||||||
|
if (ignoreMissing) return null;
|
||||||
|
else throw new UserNotFoundError(email);
|
||||||
|
}
|
||||||
let role = await coll_role.findOne({ _id: udoc.role || 'default' });
|
let role = await coll_role.findOne({ _id: udoc.role || 'default' });
|
||||||
udoc.perm = role.perm;
|
udoc.perm = role.perm;
|
||||||
return new USER(udoc);
|
return new USER(udoc);
|
||||||
@@ -73,7 +77,7 @@ async function changePassword(uid, currentPassword, newPassword) {
|
|||||||
$set: { salt, hash: pwhash.hash(newPassword, salt) }
|
$set: { salt, hash: pwhash.hash(newPassword, salt) }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async function create({ uid, email, uname, password, regip, perm = this.perm.PERM_DEFAULT || 0 }) {
|
async function create({ uid, email, uname, password, regip = '127.0.0.1', role = 'default' }) {
|
||||||
validator.checkUname(uname);
|
validator.checkUname(uname);
|
||||||
validator.checkPassword(password);
|
validator.checkPassword(password);
|
||||||
validator.checkEmail(email);
|
validator.checkEmail(email);
|
||||||
@@ -81,21 +85,22 @@ async function create({ uid, email, uname, password, regip, perm = this.perm.PER
|
|||||||
if (!uid) uid = system.incUserCounter();
|
if (!uid) uid = system.incUserCounter();
|
||||||
try {
|
try {
|
||||||
await coll.insertOne({
|
await coll.insertOne({
|
||||||
|
_id: uid,
|
||||||
email,
|
email,
|
||||||
emailLower: email.strip().toLowerCase(),
|
emailLower: email.trim().toLowerCase(),
|
||||||
uname,
|
uname,
|
||||||
unameLower: uname.strip().toLowerCase(),
|
unameLower: uname.trim().toLowerCase(),
|
||||||
password: pwhash.hash(password, salt),
|
password: pwhash.hash(password, salt),
|
||||||
salt,
|
salt,
|
||||||
regat: new Date(),
|
regat: new Date(),
|
||||||
regip,
|
regip,
|
||||||
loginat: new Date(),
|
loginat: new Date(),
|
||||||
loginip: regip,
|
loginip: regip,
|
||||||
perm,
|
role,
|
||||||
gravatar: email
|
gravatar: email
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new UserAlreadyExistError(uid, uname, email);
|
throw new UserAlreadyExistError([uid, uname, email]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -34,7 +34,8 @@ let options = {
|
|||||||
secure: false,
|
secure: false,
|
||||||
domain: '127.0.0.1',
|
domain: '127.0.0.1',
|
||||||
saved_expire_seconds: 3600 * 24,
|
saved_expire_seconds: 3600 * 24,
|
||||||
unsaved_expire_seconds: 600
|
unsaved_expire_seconds: 600,
|
||||||
|
registration_token_expire_seconds: 600
|
||||||
},
|
},
|
||||||
constants: {
|
constants: {
|
||||||
PROBLEM_PER_PAGE: 100,
|
PROBLEM_PER_PAGE: 100,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{% set page_name = "user_register" %}
|
||||||
{% extends "layout/immersive.html" %}
|
{% extends "layout/immersive.html" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row"><div class="columns">
|
<div class="row"><div class="columns">
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{% set page_name = "user_register_with_code" %}
|
||||||
{% extends "layout/immersive.html" %}
|
{% extends "layout/immersive.html" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="immersive--content immersive--center">
|
<div class="immersive--content immersive--center">
|
||||||
@@ -6,7 +7,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<label class="inverse material textbox">
|
<label class="inverse material textbox">
|
||||||
{{ _('Email') }}
|
{{ _('Email') }}
|
||||||
<input type="text" value="{{ mail }}" disabled>
|
<input type="text" value="{{ email }}" disabled>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in new issue
Block a user