All files / koa/auth auth.service.js

69.77% Statements 30/43
59.09% Branches 13/22
81.82% Functions 9/11
72.5% Lines 29/40

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95    5x 5x 5x 5x 5x     8x                               90x     61x       61x 7x   61x                     85x     61x 48x     48x 48x 48x 48x           35x 35x     29x 25x   4x             5x                           5x 5x 5x 5x 5x
'use strict'
 
const horseJwt = require('koa-jwt')
const jwt = require('jsonwebtoken')
const compose = require('koa-compose')
const { User } = require('../app/model')
const config = require('../config/env')
 
function signToken(id, role) {
  return jwt.sign({ _id: id, role }, config.session.secret, {
    expiresIn: config.session.cookie.maxAge / 1000, // 30d
  })
}
 
function setTokenCookie(ctx) {
  if (!ctx.req.user) {
    ctx.status(404);
    return ctx.body('It looks like you aren\'t logged in, please try again.');
  }
  let token = signToken(ctx.req.user._id, ctx.req.user.role);
  ctx.cookies.set('token', token);
  ctx.redirect('/');
}
 
function authToken() {
  return compose([
    async(ctx, next) => {
      // allow access_token to be passed through query parameter as well
      Iif (ctx.query && ctx.query.access_token) {
        ctx.headers.authorization = `Bearer ${ctx.query.access_token}`;
      }
      // IE11 forgets to set Authorization header sometimes. Pull from cookie instead.
      if (ctx.query && typeof ctx.headers.authorization === 'undefined') {
        ctx.headers.authorization = `Bearer ${ctx.cookies.token}`;
      }
      await next()
    },
    horseJwt({
      secret: config.session.secret,
      passthrough: true,
      // credentialsRequired: credentialsRequired, // 是否抛出错误
    }),
  ])
}
 
function isAuthenticated() {
  return compose([
    authToken(),
    async(ctx, next) => {
      if (!ctx.state.user) { ctx.throw(401, 'UnauthorizedError') }
      await next()
    },
    async(ctx, next) => {
      var user = await User.findById(ctx.state.user._id)
      Iif (!user) { ctx.throw(401, 'UnauthorizedError') }
      ctx.req.user = user
      await next()
    },
  ])
}
 
function hasRole(roleRequired) {
  Iif (!roleRequired) { this.throw('Required role needs to be set') }
  return compose([
    isAuthenticated(),
    async(ctx, next) => {
      if (config.userRoles.indexOf(ctx.req.user.role) >= config.userRoles.indexOf(roleRequired)) {
        await next()
      } else {
        ctx.throw(403, 'Forbidden')
      }
    },
  ])
}
 
function snsPassport() {
  return compose([
    authToken(),
    async(ctx, next) => {
      ctx.session.passport = {
        redirectUrl: ctx.query.redirectUrl || '/',
      }
      if (ctx.state.user) {
        ctx.session.passport.userId = ctx.state.user._id
      }
      await next()
    },
  ])
}
 
exports.signToken = signToken
exports.setTokenCookie = setTokenCookie
exports.isAuthenticated = isAuthenticated
exports.hasRole = hasRole
exports.snsPassport = snsPassport