Skip to content

Commit

Permalink
fix: add permissions to resolvers
Browse files Browse the repository at this point in the history
  • Loading branch information
NGPixel committed Oct 16, 2023
1 parent 88197c1 commit 2a3e140
Show file tree
Hide file tree
Showing 21 changed files with 459 additions and 255 deletions.
6 changes: 5 additions & 1 deletion server/core/auth.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ export default {
* @param {Express Next Callback} next
*/
authenticate (req, res, next) {
req.isAuthenticated = false

WIKI.auth.passport.authenticate('jwt', { session: false }, async (err, user, info) => {
if (err) { return next() }
let mustRevalidate = false
Expand Down Expand Up @@ -170,6 +172,7 @@ export default {
WIKI.auth.guest.cacheExpiration = DateTime.utc().plus({ minutes: 1 })
}
req.user = WIKI.auth.guest
req.isAuthenticated = false
return next()
}

Expand Down Expand Up @@ -203,6 +206,7 @@ export default {
// JWT is valid
req.logIn(user, { session: false }, (errc) => {
if (errc) { return next(errc) }
req.isAuthenticated = true
next()
})
})(req, res, next)
Expand All @@ -223,7 +227,7 @@ export default {
return true
}

// Check Global Permissions
// Check Permissions
if (_.intersection(userPermissions, permissions).length < 1) {
return false
}
Expand Down
26 changes: 19 additions & 7 deletions server/graph/resolvers/authentication.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ export default {
* List of API Keys
*/
async apiKeys (obj, args, context) {
if (!WIKI.auth.checkAccess(context.req.user, ['read:api', 'manage:api'])) {
throw new Error('ERR_FORBIDDEN')
}

const keys = await WIKI.db.apiKeys.query().orderBy(['isRevoked', 'name'])
return keys.map(k => ({
id: k.id,
Expand All @@ -31,7 +35,11 @@ export default {
/**
* Current API State
*/
apiState () {
apiState (obj, args, context) {
if (!WIKI.auth.checkAccess(context.req.user, ['read:api', 'manage:api', 'read:dashboard'])) {
throw new Error('ERR_FORBIDDEN')
}

return WIKI.config.api.isEnabled
},
/**
Expand Down Expand Up @@ -82,6 +90,10 @@ export default {
*/
async createApiKey (obj, args, context) {
try {
if (!WIKI.auth.checkAccess(context.req.user, ['manage:api'])) {
throw new Error('ERR_FORBIDDEN')
}

const key = await WIKI.db.apiKeys.createNewKey(args)
await WIKI.auth.reloadApiKeys()
WIKI.events.outbound.emit('reloadApiKeys')
Expand Down Expand Up @@ -136,7 +148,7 @@ export default {
try {
const userId = context.req.user?.id
if (!userId) {
throw new Error('ERR_USER_NOT_AUTHENTICATED')
throw new Error('ERR_NOT_AUTHENTICATED')
}

const usr = await WIKI.db.users.query().findById(userId)
Expand Down Expand Up @@ -182,7 +194,7 @@ export default {
try {
const userId = context.req.user?.id
if (!userId) {
throw new Error('ERR_USER_NOT_AUTHENTICATED')
throw new Error('ERR_NOT_AUTHENTICATED')
}

const usr = await WIKI.db.users.query().findById(userId)
Expand Down Expand Up @@ -224,7 +236,7 @@ export default {
try {
const userId = context.req.user?.id
if (!userId) {
throw new Error('ERR_USER_NOT_AUTHENTICATED')
throw new Error('ERR_NOT_AUTHENTICATED')
}

const usr = await WIKI.db.users.query().findById(userId)
Expand Down Expand Up @@ -283,7 +295,7 @@ export default {
try {
const userId = context.req.user?.id
if (!userId) {
throw new Error('ERR_USER_NOT_AUTHENTICATED')
throw new Error('ERR_NOT_AUTHENTICATED')
}

const usr = await WIKI.db.users.query().findById(userId)
Expand Down Expand Up @@ -346,7 +358,7 @@ export default {
try {
const userId = context.req.user?.id
if (!userId) {
throw new Error('ERR_USER_NOT_AUTHENTICATED')
throw new Error('ERR_NOT_AUTHENTICATED')
}

const usr = await WIKI.db.users.query().findById(userId)
Expand Down Expand Up @@ -584,7 +596,7 @@ export default {
*/
async revokeApiKey (obj, args, context) {
try {
if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) {
if (!WIKI.auth.checkAccess(context.req.user, ['manage:api'])) {
throw new Error('ERR_FORBIDDEN')
}

Expand Down
3 changes: 3 additions & 0 deletions server/graph/resolvers/block.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ export default {
Mutation: {
async setBlocksState(obj, args, context) {
try {
if (!WIKI.auth.checkAccess(context.req.user, ['manage:blocks'])) {
throw new Error('ERR_FORBIDDEN')
}
// TODO: update blocks state
return {
operation: generateSuccess('Blocks state updated successfully')
Expand Down
30 changes: 25 additions & 5 deletions server/graph/resolvers/hooks.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,31 @@ import _ from 'lodash-es'

export default {
Query: {
async hooks () {
async hooks (obj, args, context) {
if (!WIKI.auth.checkAccess(context.req.user, ['read:webhooks', 'write:webhooks', 'manage:webhooks'])) {
throw new Error('ERR_FORBIDDEN')
}

return WIKI.db.hooks.query().orderBy('name')
},
async hookById (obj, args) {
async hookById (obj, args, context) {
if (!WIKI.auth.checkAccess(context.req.user, ['read:webhooks', 'write:webhooks', 'manage:webhooks'])) {
throw new Error('ERR_FORBIDDEN')
}

return WIKI.db.hooks.query().findById(args.id)
}
},
Mutation: {
/**
* CREATE HOOK
*/
async createHook (obj, args) {
async createHook (obj, args, context) {
try {
if (!WIKI.auth.checkAccess(context.req.user, ['write:webhooks', 'manage:webhooks'])) {
throw new Error('ERR_FORBIDDEN')
}

// -> Validate inputs
if (!args.name || args.name.length < 1) {
throw new WIKI.Error.Custom('HookCreateInvalidName', 'Invalid Hook Name')
Expand All @@ -41,8 +53,12 @@ export default {
/**
* UPDATE HOOK
*/
async updateHook (obj, args) {
async updateHook (obj, args, context) {
try {
if (!WIKI.auth.checkAccess(context.req.user, ['manage:webhooks'])) {
throw new Error('ERR_FORBIDDEN')
}

// -> Load hook
const hook = await WIKI.db.hooks.query().findById(args.id)
if (!hook) {
Expand Down Expand Up @@ -72,8 +88,12 @@ export default {
/**
* DELETE HOOK
*/
async deleteHook (obj, args) {
async deleteHook (obj, args, context) {
try {
if (!WIKI.auth.checkAccess(context.req.user, ['manage:webhooks'])) {
throw new Error('ERR_FORBIDDEN')
}

await WIKI.db.hooks.deleteHook(args.id)
WIKI.logger.debug(`Hook ${args.id} deleted successfully.`)
return {
Expand Down
43 changes: 0 additions & 43 deletions server/graph/resolvers/localization.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { generateError, generateSuccess } from '../../helpers/graph.mjs'
import _ from 'lodash-es'

export default {
Query: {
async locales(obj, args, context, info) {
Expand All @@ -9,45 +6,5 @@ export default {
localeStrings (obj, args, context, info) {
return WIKI.db.locales.getStrings(args.locale)
}
},
Mutation: {
async downloadLocale(obj, args, context) {
try {
const job = await WIKI.scheduler.registerJob({
name: 'fetch-graph-locale',
immediate: true
}, args.locale)
await job.finished
return {
responseResult: generateSuccess('Locale downloaded successfully')
}
} catch (err) {
return generateError(err)
}
},
async updateLocale(obj, args, context) {
try {
WIKI.config.lang.code = args.locale
WIKI.config.lang.autoUpdate = args.autoUpdate
WIKI.config.lang.namespacing = args.namespacing
WIKI.config.lang.namespaces = _.union(args.namespaces, [args.locale])

const newLocale = await WIKI.db.locales.query().select('isRTL').where('code', args.locale).first()
WIKI.config.lang.rtl = newLocale.isRTL

await WIKI.configSvc.saveToDb(['lang'])

await WIKI.lang.setCurrentLocale(args.locale)
await WIKI.lang.refreshNamespaces()

await WIKI.cache.del('nav:locales')

return {
responseResult: generateSuccess('Locale config updated')
}
} catch (err) {
return generateError(err)
}
}
}
}
14 changes: 13 additions & 1 deletion server/graph/resolvers/mail.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import { generateError, generateSuccess } from '../../helpers/graph.mjs'

export default {
Query: {
async mailConfig(obj, args, context, info) {
async mailConfig(obj, args, context) {
if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) {
throw new Error('ERR_FORBIDDEN')
}

return {
...WIKI.config.mail,
pass: WIKI.config.mail.pass.length > 0 ? '********' : ''
Expand All @@ -13,6 +17,10 @@ export default {
Mutation: {
async sendMailTest(obj, args, context) {
try {
if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) {
throw new Error('ERR_FORBIDDEN')
}

if (_.isEmpty(args.recipientEmail) || args.recipientEmail.length < 6) {
throw new WIKI.Error.MailInvalidRecipient()
}
Expand All @@ -36,6 +44,10 @@ export default {
},
async updateMailConfig(obj, args, context) {
try {
if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) {
throw new Error('ERR_FORBIDDEN')
}

WIKI.config.mail = {
senderName: args.senderName,
senderEmail: args.senderEmail,
Expand Down
57 changes: 37 additions & 20 deletions server/graph/resolvers/page.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import _ from 'lodash-es'
import { generateError, generateSuccess } from '../../helpers/graph.mjs'
import { parsePath }from '../../helpers/page.mjs'
import { parsePath } from '../../helpers/page.mjs'
import tsquery from 'pg-tsquery'

const tsq = tsquery()
Expand Down Expand Up @@ -247,12 +247,19 @@ export default {
siteId: args.siteId
})
if (page) {
return {
...page,
...page.config,
scriptCss: page.scripts?.css,
scriptJsLoad: page.scripts?.jsLoad,
scriptJsUnload: page.scripts?.jsUnload
if (WIKI.auth.checkAccess(context.req.user, ['read:pages'], {
path: page.path,
locale: page.locale
})) {
return {
...page,
...page.config,
scriptCss: page.scripts?.css,
scriptJsLoad: page.scripts?.jsLoad,
scriptJsUnload: page.scripts?.jsUnload
}
} else {
throw new Error('ERR_FORBIDDEN')
}
} else {
throw new Error('ERR_PAGE_NOT_FOUND')
Expand All @@ -265,17 +272,17 @@ export default {
async pathFromAlias (obj, args, context, info) {
const alias = args.alias?.trim()
if (!alias) {
throw new Error('ERR_ALIAS_MISSING')
throw new Error('ERR_PAGE_ALIAS_MISSING')
}
if (!WIKI.sites[args.siteId]) {
throw new Error('ERR_INVALID_SITE_ID')
throw new Error('ERR_INVALID_SITE')
}
const page = await WIKI.db.pages.query().findOne({
alias: args.alias,
siteId: args.siteId
}).select('id', 'path', 'locale')
if (!page) {
throw new Error('ERR_ALIAS_NOT_FOUND')
throw new Error('ERR_PAGE_ALIAS_NOT_FOUND')
}
return {
id: page.id,
Expand All @@ -287,7 +294,7 @@ export default {
* FETCH TAGS
*/
async tags (obj, args, context, info) {
if (!args.siteId) { throw new Error('Missing Site ID')}
if (!args.siteId) { throw new Error('Missing Site ID') }
const tags = await WIKI.db.knex('tags').where('siteId', args.siteId).orderBy('tag')
// TODO: check permissions
return tags
Expand Down Expand Up @@ -670,19 +677,29 @@ export default {
}
},
Page: {
icon (obj) {
return obj.icon || 'las la-file-alt'
icon (page) {
return page.icon || 'las la-file-alt'
},
password (page) {
return page.password ? '********' : ''
},
password (obj) {
return obj.password ? '********' : ''
content (page, args, context) {
if (!WIKI.auth.checkAccess(context.req.user, ['read:source', 'write:pages', 'manage:pages'], {
path: page.path,
locale: page.locale
})) {
throw new Error('ERR_FORBIDDEN')
}

return page.content
},
// async tags (obj) {
// return WIKI.db.pages.relatedQuery('tags').for(obj.id)
// async tags (page) {
// return WIKI.db.pages.relatedQuery('tags').for(page.id)
// },
tocDepth (obj) {
tocDepth (page) {
return {
min: obj.extra?.tocDepth?.min ?? 1,
max: obj.extra?.tocDepth?.max ?? 2
min: page.extra?.tocDepth?.min ?? 1,
max: page.extra?.tocDepth?.max ?? 2
}
}
// comments(pg) {
Expand Down
Loading

0 comments on commit 2a3e140

Please sign in to comment.