@ -1,13 +1,14 @@
|
||||
query {
|
||||
authentication {
|
||||
strategies(
|
||||
filter: "isEnabled eq true",
|
||||
orderBy: "title ASC"
|
||||
isEnabled: true
|
||||
) {
|
||||
key
|
||||
title
|
||||
useForm
|
||||
icon
|
||||
color
|
||||
selfRegistration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
.md2 {
|
||||
|
||||
&.v-text-field .v-input__slot {
|
||||
border-radius: 28px;
|
||||
}
|
||||
|
||||
}
|
Before Width: | Height: | Size: 522 B After Width: | Height: | Size: 1005 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 469 B |
After Width: | Height: | Size: 783 B |
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
@ -0,0 +1,54 @@
|
||||
const { SchemaDirectiveVisitor } = require('graphql-tools')
|
||||
const { defaultFieldResolver } = require('graphql')
|
||||
|
||||
class AuthDirective extends SchemaDirectiveVisitor {
|
||||
visitObject(type) {
|
||||
this.ensureFieldsWrapped(type)
|
||||
type._requiredAuthScopes = this.args.requires
|
||||
}
|
||||
// Visitor methods for nested types like fields and arguments
|
||||
// also receive a details object that provides information about
|
||||
// the parent and grandparent types.
|
||||
visitFieldDefinition(field, details) {
|
||||
this.ensureFieldsWrapped(details.objectType)
|
||||
field._requiredAuthScopes = this.args.requires
|
||||
}
|
||||
|
||||
visitArgumentDefinition(argument, details) {
|
||||
this.ensureFieldsWrapped(details.objectType)
|
||||
argument._requiredAuthScopes = this.args.requires
|
||||
}
|
||||
|
||||
ensureFieldsWrapped(objectType) {
|
||||
// Mark the GraphQLObjectType object to avoid re-wrapping:
|
||||
if (objectType._authFieldsWrapped) return
|
||||
objectType._authFieldsWrapped = true
|
||||
|
||||
const fields = objectType.getFields()
|
||||
|
||||
Object.keys(fields).forEach(fieldName => {
|
||||
const field = fields[fieldName]
|
||||
const { resolve = defaultFieldResolver } = field
|
||||
field.resolve = async function (...args) {
|
||||
// Get the required scopes from the field first, falling back
|
||||
// to the objectType if no scopes is required by the field:
|
||||
const requiredScopes = field._requiredAuthScopes || objectType._requiredAuthScopes
|
||||
|
||||
if (!requiredScopes) {
|
||||
return resolve.apply(this, args)
|
||||
}
|
||||
|
||||
const context = args[2]
|
||||
console.info(context.req.user)
|
||||
// const user = await getUser(context.headers.authToken)
|
||||
// if (!user.hasRole(requiredScopes)) {
|
||||
// throw new Error('not authorized')
|
||||
// }
|
||||
|
||||
return resolve.apply(this, args)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AuthDirective
|
@ -1,33 +1,75 @@
|
||||
const jwt = require('jsonwebtoken')
|
||||
const moment = require('moment')
|
||||
|
||||
const securityHelper = require('../helpers/security')
|
||||
|
||||
/* global WIKI */
|
||||
|
||||
/**
|
||||
* Authentication middleware
|
||||
*/
|
||||
module.exports = (req, res, next) => {
|
||||
// Is user authenticated ?
|
||||
module.exports = {
|
||||
jwt(req, res, next) {
|
||||
WIKI.auth.passport.authenticate('jwt', {session: false}, async (err, user, info) => {
|
||||
if (err) { return next() }
|
||||
|
||||
console.info(err, user, info)
|
||||
|
||||
// Expired but still valid within 7 days, just renew
|
||||
if (info instanceof jwt.TokenExpiredError && moment().subtract(7, 'days').isBefore(info.expiredAt)) {
|
||||
const jwtPayload = jwt.decode(securityHelper.extractJWT(req))
|
||||
console.info(jwtPayload)
|
||||
try {
|
||||
const newToken = await WIKI.models.users.refreshToken(jwtPayload.id)
|
||||
user = newToken.user
|
||||
|
||||
// Try headers, otherwise cookies for response
|
||||
if (req.get('content-type') === 'application/json') {
|
||||
res.headers('new-jwt', newToken.token)
|
||||
} else {
|
||||
res.cookie('jwt', newToken.token, { expires: moment().add(7, 'days').toDate() })
|
||||
}
|
||||
} catch (err) {
|
||||
return next()
|
||||
}
|
||||
}
|
||||
|
||||
if (!req.isAuthenticated()) {
|
||||
if (WIKI.config.public !== true) {
|
||||
return res.redirect('/login')
|
||||
// JWT is NOT valid
|
||||
if (!user) { return next() }
|
||||
|
||||
// JWT is valid
|
||||
req.logIn(user, { session: false }, (err) => {
|
||||
if (err) { return next(err) }
|
||||
next()
|
||||
})
|
||||
})(req, res, next)
|
||||
},
|
||||
checkPath(req, res, next) {
|
||||
// Is user authenticated ?
|
||||
|
||||
if (!req.isAuthenticated()) {
|
||||
if (WIKI.config.public !== true) {
|
||||
return res.redirect('/login')
|
||||
} else {
|
||||
// req.user = rights.guest
|
||||
res.locals.isGuest = true
|
||||
}
|
||||
} else {
|
||||
// req.user = rights.guest
|
||||
res.locals.isGuest = true
|
||||
res.locals.isGuest = false
|
||||
}
|
||||
} else {
|
||||
res.locals.isGuest = false
|
||||
}
|
||||
|
||||
// Check permissions
|
||||
// Check permissions
|
||||
|
||||
// res.locals.rights = rights.check(req)
|
||||
// res.locals.rights = rights.check(req)
|
||||
|
||||
// if (!res.locals.rights.read) {
|
||||
// return res.render('error-forbidden')
|
||||
// }
|
||||
// if (!res.locals.rights.read) {
|
||||
// return res.render('error-forbidden')
|
||||
// }
|
||||
|
||||
// Expose user data
|
||||
// Expose user data
|
||||
|
||||
res.locals.user = req.user
|
||||
res.locals.user = req.user
|
||||
|
||||
return next()
|
||||
return next()
|
||||
}
|
||||
}
|
||||
|