Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const session = require('koa-generic-session');
- const mongooseStore = require('koa-session-mongoose');
- const convert = require('koa-convert');
- exports.init = app => app.use(convert(session({
- key: 'sid',
- cookie: {
- httpOnly: true,
- path: '/',
- overwrite: true,
- signed: false, // by default true (not needed here)
- maxAge: 3600 * 4 * 1e3 // session expires in 4 hours, remember me lives longer
- },
- // touch session.updatedAt in DB & reset cookie on every visit to prolong the session
- // koa-session-mongoose resaves the session as a whole, not just a single field
- rolling: true,
- store: mongooseStore.create({
- model: 'Session',
- expires: 3600 * 4
- })
- })));
- const passport = require('../libs/passport');
- exports.init = app => app.use(passport.initialize());
- exports.init = app => app.use(require('koa-passport').session());
- exports.init = app => app.use(async function(ctx, next) {
- // keep previous flash
- let messages = ctx.session.messages || {};
- // clear all flash
- delete ctx.session.messages;
- ctx.flash = function(type, html) {
- if (type === undefined) {
- return messages || {};
- }
- if (html === undefined) {
- return messages[type] || [];
- }
- if (!ctx.session.messages) {
- ctx.session.messages = {};
- }
- if (!ctx.session.messages[type]) {
- ctx.session.messages[type] = [];
- }
- ctx.session.messages[type].push(html);
- };
- await next();
- // note that ctx.session can be null after other middlewares,
- // e.g. logout does session.destroy()
- if (!ctx.session) return;
- if (ctx.status == 302 && !ctx.session.messages) {
- // pass on the flash over a redirect
- ctx.session.messages = messages;
- }
- });
- const CSRF = require('koa-csrf').default;
- exports.init = app => app.use(new CSRF({
- invalidSessionSecretMessage: 'Invalid session secret',
- invalidSessionSecretStatusCode: 403,
- invalidTokenMessage: 'Invalid CSRF token',
- invalidTokenStatusCode: 403,
- excludedMethods: [ 'GET', 'HEAD', 'OPTIONS' ],
- disableQuery: false
- }));
- const mongoose = require('mongoose');
- const crypto = require('crypto');
- const _ = require('lodash');
- const config = require('config');
- const userSchema = new mongoose.Schema({
- displayName: {
- type: String,
- required: "Имя пользователя отсутствует."
- },
- email: {
- type: String,
- unique: true,
- required: "E-mail пользователя не должен быть пустым.",
- validate: [
- {
- validator: function checkEmail(value) {
- return this.deleted ? true : /^[-.\w]+@([\w-]+\.)+[\w-]{2,12}$/.test(value);
- },
- msg: 'Укажите, пожалуйста, корректный email.'
- }
- ]
- },
- deleted: Boolean,
- // ('asdfjasdfahsdf' + 'password') => 'sdfashfkjaw76f48afasdf'
- passwordHash: {
- type: String,
- required: true
- },
- salt: {
- required: true,
- type: String
- }
- }, {
- timestamps: true
- });
- userSchema.virtual('password')
- .set(function(password) {
- if (password !== undefined) {
- if (password.length < 4) {
- this.invalidate('password', 'Пароль должен быть минимум 4 символа.');
- }
- }
- this._plainPassword = password;
- if (password) {
- this.salt = crypto.randomBytes(config.crypto.hash.length).toString('base64');
- this.passwordHash = crypto.pbkdf2Sync(
- password,
- this.salt,
- config.crypto.hash.iterations,
- config.crypto.hash.length,
- 'sha1'
- ).toString('base64');
- } else {
- // remove password (unable to login w/ password any more, but can use providers)
- this.salt = undefined;
- this.passwordHash = undefined;
- }
- })
- .get(function() {
- return this._plainPassword;
- });
- userSchema.methods.checkPassword = function(password) {
- if (!password) return false; // empty password means no login by password
- if (!this.passwordHash) return false; // this user does not have password (the line below would hang!)
- return crypto.pbkdf2Sync(
- password,
- this.salt,
- config.crypto.hash.iterations,
- config.crypto.hash.length,
- 'sha1'
- ).toString('base64') == this.passwordHash;
- };
- module.exports = mongoose.model('User', userSchema);
- const passport = require('koa-passport');
- exports.post = async function(ctx, next) {
- // запускает стратегию, станадартные опции что делать с результатом
- // опции @https://github.com/jaredhanson/passport/blob/master/lib/middleware/authenticate.js
- // можно передать и функцию
- await passport.authenticate('local', {
- successRedirect: '/',
- failureRedirect: '/',
- //failureMessage: true // запишет сообщение об ошибке в session.messages[]
- failureFlash: true // req.flash, better
- })(ctx, next);
- };
- exports.get = async function(ctx, next) {
- if (ctx.isAuthenticated()) {
- ctx.body = ctx.render('welcome');
- } else {
- ctx.body = ctx.render('login');
- }
- };
- exports.post = async function(ctx, next) {
- ctx.logout();
- ctx.session = null; // destroy session (!!!)
- ctx.redirect('/');
- };
- const passport = require('koa-passport');
- const User = require('../models/user');
- const pick = require('lodash/pick');
- exports.get = async function(ctx, next) {
- ctx.body = ctx.render('registration');
- };
- exports.post = async function(ctx, next) {
- const user = await User.create(pick(ctx.request.body, User.publicFields));
- // ctx.flash('error', 'message');
- // ctx.redirect('/registration');
- await ctx.login(user);
- ctx.redirect('/');
- };
- const Koa = require('koa');
- const app = new Koa();
- const config = require('config');
- const mongoose = require('./libs/mongoose');
- const path = require('path');
- const fs = require('fs');
- app.keys = [config.get('secret')];
- const handlers = fs.readdirSync(path.join(__dirname, 'middlewares')).sort();
- handlers.forEach(handler => require('./middlewares/' + handler).init(app));
- // ---------------------------------------
- // can be split into files too
- const Router = require('koa-router');
- const router = new Router();
- router.get('/', require('./routes/frontpage').get);
- router.post('/login', require('./routes/login').post);
- router.post('/logout', require('./routes/logout').post);
- // router.get('/', require('./routes/login').post);
- app.use(router.routes());
- app.listen(3000);
- const passport = require('koa-passport');
- const User = require('../../models/user');
- require('./serialize');
- require('./localStrategy');
- module.exports = passport;
- let passport = require('koa-passport');
- let LocalStrategy = require('passport-local');
- let User = require('../../models/user');
- passport.use(new LocalStrategy({
- usernameField: 'email', // 'username' by default
- passwordField: 'password',
- passReqToCallback: true // req for more complex cases
- },
- // TODO: rewrite this, use async/await
- function(req, email, password, done) {
- User.findOne({ email }, (err, user) => {
- if (err) {
- return done(err);
- }
- if (!user || !user.checkPassword(password)) {
- // don't say whether the user exists
- return done(null, false, { message: 'Нет такого пользователя или пароль неверен.' });
- }
- return done(null, user);
- });
- }
- ));
- const User = require('../../models/user');
- const passport = require('koa-passport');
- // паспорт напрямую с базой не работает
- passport.serializeUser(function(user, done) {
- done(null, user.email); // uses _id as idField
- });
- passport.deserializeUser(function(email, done) {
- User.findOne({email:email}, done); // callback version checks id validity automatically
- });
- const promisify = require('es6-promisify');
- const assert = require('assert');
- const mongoose = require('./mongoose');
- module.exports = async function clearDatabase() {
- if (mongoose.connection.readyState == 2) { // connecting
- await promisify(cb => mongoose.connection.on('open', cb))();
- }
- assert(mongoose.connection.readyState == 1);
- const db = mongoose.connection.db;
- let collections = await promisify(cb => db.listCollections().toArray(cb))();
- collections = collections
- .filter(coll => !coll.name.startsWith('system.'))
- .map(coll => db.collection(coll.name)); // plain object with info => collection object
- await Promise.all(
- // collections.map(coll => promisify(cb => coll.drop(cb))())
- collections.map(coll => promisify(coll.drop, coll)())
- );
- await Promise.all(mongoose.modelNames().map(async function(modelName) {
- const model = mongoose.model(modelName);
- return promisify(cb => model.ensureIndexes(cb))();
- }));
- };
- const mongoose = require('./mongoose');
- module.exports = async function (models) {
- let promises = [];
- for (let name in models) {
- let modelObjects = models[name];
- for (let modelObject of modelObjects) {
- promises.push(mongoose.model(name).create(modelObject));
- }
- }
- await Promise.all(promises);
- };
- const mongoose = require('mongoose');
- const config = require('config');
- mongoose.Promise = Promise;
- if (process.env.MONGOOSE_DEBUG) {
- mongoose.set('debug', true);
- }
- mongoose.connect(config.mongoose.uri, config.mongoose.options);
- module.exports = mongoose;
- // generate a valid object id from an arbitrary string
- const crypto = require('crypto');
- // oid('course1') => generates always same id
- module.exports = function oid(str) {
- return crypto.createHash('md5').update(str).digest('hex').substring(0, 24);
- };
- exports.withTime = oidWithTime;
- function oidWithTime(str) {
- const time = Math.floor(Date.now() / 1000).toString(16);
- while (time.length < 8) { // never happens in real-life though
- time = '0' + time;
- }
- return time + crypto.createHash('md5').update(str).digest('hex').substring(0, 16);
- }
Add Comment
Please, Sign In to add comment