diff options
Diffstat (limited to 'src/api/private')
| -rw-r--r-- | src/api/private/signin.ts | 57 | ||||
| -rw-r--r-- | src/api/private/signup.ts | 94 |
2 files changed, 151 insertions, 0 deletions
diff --git a/src/api/private/signin.ts b/src/api/private/signin.ts new file mode 100644 index 0000000000..b68fc89aa0 --- /dev/null +++ b/src/api/private/signin.ts @@ -0,0 +1,57 @@ +import * as express from 'express'; +import * as bcrypt from 'bcrypt'; +import User from '../models/user'; +import Signin from '../models/signin'; +import serialize from '../serializers/signin'; +import event from '../event'; + + +export default async (req: express.Request, res: express.Response) => { + res.header('Access-Control-Allow-Credentials', 'true'); + + const username = req.body['username']; + const password = req.body['password']; + + // Fetch user + const user = await User.findOne({ + username_lower: username.toLowerCase() + }); + + if (user === null) { + res.status(404).send('user not found'); + return; + } + + // Compare password + const same = await bcrypt.compare(password, user.password); + + if (same) { + const expires = 1000 * 60 * 60 * 24 * 365; // One Year + res.cookie('i', user.token, { + path: '/', + domain: `.${config.host}`, + secure: config.url.substr(0, 5) === 'https', + httpOnly: false, + expires: new Date(Date.now() + expires), + maxAge: expires + }); + + res.sendStatus(204); + } else { + res.status(400).send('incorrect password'); + } + + // Append signin history + const inserted = await Signin.insert({ + created_at: new Date(), + user_id: user._id, + ip: req.ip, + headers: req.headers, + success: same + }); + + const record = inserted.ops[0]; + + // Publish signin event + event(user._id, 'signin', await serialize(record)); +}; diff --git a/src/api/private/signup.ts b/src/api/private/signup.ts new file mode 100644 index 0000000000..7df1f25b37 --- /dev/null +++ b/src/api/private/signup.ts @@ -0,0 +1,94 @@ +import * as express from 'express'; +import * as bcrypt from 'bcrypt'; +import rndstr from 'rndstr'; +const recaptcha = require('recaptcha-promise'); +import User from '../models/user'; +import { validateUsername } from '../models/user'; +import serialize from '../serializers/user'; + + +recaptcha.init({ + secret_key: config.recaptcha.secretKey +}); + +export default async (req: express.Request, res: express.Response) => { + // Verify recaptcha + const success = await recaptcha(req.body['g-recaptcha-response']); + + if (!success) { + res.status(400).send('recaptcha-failed'); + return; + } + + const username = req.body['username']; + const password = req.body['password']; + const name = 'ๅ็กใ'; + + // Validate username + if (!validateUsername(username)) { + res.sendStatus(400); + return; + } + + // Fetch exist user that same username + const usernameExist = await User + .count({ + username_lower: username.toLowerCase() + }, { + limit: 1 + }); + + // Check username already used + if (usernameExist !== 0) { + res.sendStatus(400); + return; + } + + // Generate hash of password + const salt = bcrypt.genSaltSync(14); + const hash = bcrypt.hashSync(password, salt); + + // Generate secret + const secret = rndstr('a-zA-Z0-9', 32); + + // Create account + const inserted = await User.insert({ + token: secret, + avatar_id: null, + banner_id: null, + birthday: null, + created_at: new Date(), + bio: null, + email: null, + followers_count: 0, + following_count: 0, + links: null, + location: null, + name: name, + password: hash, + posts_count: 0, + likes_count: 0, + liked_count: 0, + drive_capacity: 1073741824, // 1GB + username: username, + username_lower: username.toLowerCase() + }); + + const account = inserted.ops[0]; + + // Response + res.send(await serialize(account)); + + // Create search index + if (config.elasticsearch.enable) { + const es = require('../../db/elasticsearch'); + es.index({ + index: 'misskey', + type: 'user', + id: account._id.toString(), + body: { + username: username + } + }); + } +}; |