Skip to content

Commit

Permalink
feat: circumvent permission checks when developing locally via serve-…
Browse files Browse the repository at this point in the history
…dev (credits go to bradleyDean)
  • Loading branch information
l4u532 committed Dec 11, 2023
1 parent 6d30396 commit d3c2bb3
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 25 deletions.
12 changes: 12 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@
],
"console": "integratedTerminal",
},
{
"type": "node",
"request": "launch",
"name": "Launch API Server (serve-dev)",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}/src/main.ts",
"preLaunchTask": "tsc: build - tsconfig.json",
"outFiles": ["${workspaceFolder}/build/**/*.js"],
"runtimeExecutable": "yarn",
"runtimeArgs": ["run", "serve-dev"],
"console": "integratedTerminal"
},
{
"name": "Debug Jest Tests",
"type": "node",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"build-release": "tsc -p tsconfig.release.json",
"clean": "tsc -b --clean && rm -rf build/*",
"serve": "yarn build && node --experimental-json-modules build/main.js",
"serve-dev": "GOD_MODE=true yarn serve",
"refresh-db": "./refresh-db.sh",
"seed-usa": "yarn build && node build/db/import/usa/USADay0Seed.js",
"seed-db": "./seed-db.sh",
Expand Down
58 changes: 34 additions & 24 deletions src/auth/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,47 @@
import muid from 'uuid-mongodb'
import muid, { MUUID } from 'uuid-mongodb'
import { logger } from '../logger.js'
import { AuthUserType } from '../types.js'
import { verifyJWT } from './util.js'
import { logger } from '../logger.js'

/**
* Create a middleware context for Apollo server
*/
export const createContext = async ({ req }): Promise<any> => {
const { headers } = req
export const createContext = (() => {
let testUUID: MUUID

const user: AuthUserType = {
roles: [],
uuid: undefined,
isBuilder: false
if (process.env.GOD_MODE === 'true') {
testUUID = muid.v4()
logger.info('🚨🚨 GOD_MODE enabled, allowing all queries and mutations. This is ONLY for local development and should NOT happen production. 🚨🚨')
logger.info(`The user.uuid for this session is: ${testUUID.toString()}`)
}

const authHeader = String(headers?.authorization ?? '')
if (authHeader.startsWith('Bearer ')) {
const token = authHeader.substring(7, authHeader.length).trim()
// return async ({ req }: { req?: Request } = {}): Promise<any> => {
// const headers = req?.headers
return async ({ req }): Promise<any> => {
const { headers } = req

let payload
try {
payload = await verifyJWT(token)
} catch (e) {
logger.error(`Can't verify JWT token ${e.toString() as string}`)
throw new Error('An unexpected error has occurred. Please notify us at [email protected].')
const user: AuthUserType = {
roles: [],
uuid: undefined,
isBuilder: false
}

user.isBuilder = payload?.scope?.includes('builder:default') ?? false
user.roles = payload?.['https://tacos.openbeta.io/roles'] ?? []
const uidStr: string | undefined = payload?.['https://tacos.openbeta.io/uuid']
user.uuid = uidStr != null ? muid.from(uidStr) : undefined
}
if (process.env.GOD_MODE === 'true' && (user.uuid == null)) {
user.roles = ['user_admin', 'org_admin', 'editor']
user.uuid = testUUID
logger.info(`The user.roles for this session is: ${user.roles.toString()}`)
} else {
const authHeader = String(headers.authorization ?? '')
if (authHeader.startsWith('Bearer ')) {
const token = authHeader.substring(7, authHeader.length).trim()
const z = await verifyJWT(token)

return { user }
}
user.isBuilder = z?.scope?.includes('builder:default') ?? false
user.roles = z?.['https://tacos.openbeta.io/roles'] ?? []
const uidStr: string | undefined = z?.['https://tacos.openbeta.io/uuid']
user.uuid = uidStr != null ? muid.from(uidStr) : undefined
}
}
return { user }
}
})()
19 changes: 18 additions & 1 deletion src/auth/permissions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { shield, allow, and, or } from 'graphql-shield'
import { isEditor, isUserAdmin, isOwner, isValidEmail, isMediaOwner } from './rules.js'

const permissions = shield({
const defaultPermissions = shield({
Query: {
'*': allow
},
Expand All @@ -25,4 +25,21 @@ const permissions = shield({
fallbackRule: allow
})

// permissions object for when env var GOD_MODE is true
// only relevant for local development via `yarn serve-dev`
const godModePermissions = shield({
Query: {
'*': allow
},
Mutation: {
'*': allow
}
}, {
allowExternalErrors: true,
fallbackRule: allow
})

// Choose the appropriate shield based on whether env var GOD_MODE is set
const permissions = process.env.GOD_MODE === 'true' ? godModePermissions : defaultPermissions

export default permissions

0 comments on commit d3c2bb3

Please sign in to comment.