udpate auth.js to current template
This commit is contained in:
@@ -1,12 +1,13 @@
|
|||||||
import { AuthenticationError, ForbiddenError } from '@redwoodjs/graphql-server'
|
|
||||||
import { parseJWT } from '@redwoodjs/api'
|
import { parseJWT } from '@redwoodjs/api'
|
||||||
|
import { AuthenticationError, ForbiddenError } from '@redwoodjs/graphql-server'
|
||||||
import { logger } from 'src/lib/logger'
|
import { logger } from 'src/lib/logger'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getCurrentUser returns the user information together with
|
* getCurrentUser returns the user information together with
|
||||||
* an optional collection of roles used by requireAuth() to check
|
* an optional collection of roles used by requireAuth() to check
|
||||||
* if the user is authenticated or has role-based access
|
* if the user is authenticated or has role-based access
|
||||||
*
|
*
|
||||||
* @param decoded - The decoded access token containing user info and JWT claims like `sub`
|
* @param decoded - The decoded access token containing user info and JWT claims like `sub`. Note could be null.
|
||||||
* @param { token, SupportedAuthTypes type } - The access token itself as well as the auth provider type
|
* @param { token, SupportedAuthTypes type } - The access token itself as well as the auth provider type
|
||||||
* @param { APIGatewayEvent event, Context context } - An object which contains information from the invoker
|
* @param { APIGatewayEvent event, Context context } - An object which contains information from the invoker
|
||||||
* such as headers and cookies, and the context information about the invocation such as IP Address
|
* such as headers and cookies, and the context information about the invocation such as IP Address
|
||||||
@@ -32,44 +33,69 @@ export const getCurrentUser = async (
|
|||||||
return { ...decoded }
|
return { ...decoded }
|
||||||
}
|
}
|
||||||
|
|
||||||
//Taken from: https://redwoodjs.com/cookbook/role-based-access-control-rbac#how-to-code-examples
|
/**
|
||||||
|
* The user is authenticated if there is a currentUser in the context
|
||||||
|
*
|
||||||
|
* @returns {boolean} - If the currentUser is authenticated
|
||||||
|
*/
|
||||||
|
export const isAuthenticated = () => {
|
||||||
|
return !!context.currentUser
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When checking role membership, roles can be a single value, a list, or none.
|
||||||
|
* You can use Prisma enums too (if you're using them for roles), just import your enum type from `@prisma/client`
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the currentUser is authenticated (and assigned one of the given roles)
|
||||||
|
*
|
||||||
|
* @param roles: AllowedRoles - Checks if the currentUser is assigned one of these roles
|
||||||
|
*
|
||||||
|
* @returns {boolean} - Returns true if the currentUser is logged in and assigned one of the given roles,
|
||||||
|
* or when no roles are provided to check against. Otherwise returns false.
|
||||||
|
*/
|
||||||
|
export const hasRole = ({ roles }) => {
|
||||||
|
if (!isAuthenticated()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roles) {
|
||||||
|
if (Array.isArray(roles)) {
|
||||||
|
return context.currentUser.roles?.some((r) => roles.includes(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof roles === 'string') {
|
||||||
|
return context.currentUser.roles?.includes(roles)
|
||||||
|
}
|
||||||
|
|
||||||
|
// roles not found
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use requireAuth in your services to check that a user is logged in,
|
* Use requireAuth in your services to check that a user is logged in,
|
||||||
* whether or not they are assigned a role, and optionally raise an
|
* whether or not they are assigned a role, and optionally raise an
|
||||||
* error if they're not.
|
* error if they're not.
|
||||||
*
|
*
|
||||||
* @param {string=} roles - An optional role or list of roles
|
* @param roles: AllowedRoles - When checking role membership, these roles grant access.
|
||||||
* @param {array=} roles - An optional list of roles
|
|
||||||
|
|
||||||
* @example
|
|
||||||
*
|
*
|
||||||
* // checks if currentUser is authenticated
|
* @returns - If the currentUser is authenticated (and assigned one of the given roles)
|
||||||
* requireAuth()
|
|
||||||
*
|
*
|
||||||
* @example
|
* @throws {AuthenticationError} - If the currentUser is not authenticated
|
||||||
|
* @throws {ForbiddenError} If the currentUser is not allowed due to role permissions
|
||||||
*
|
*
|
||||||
* // checks if currentUser is authenticated and assigned one of the given roles
|
* @see https://github.com/redwoodjs/redwood/tree/main/packages/auth for examples
|
||||||
* requireAuth({ roles: 'editor' })
|
|
||||||
* requireAuth({ roles: ['admin', 'author', 'publisher'] })
|
|
||||||
*/
|
*/
|
||||||
export const requireAuth = ({ roles } = {}) => {
|
export const requireAuth = ({ roles }) => {
|
||||||
if (!context.currentUser) {
|
if (!isAuthenticated()) {
|
||||||
throw new AuthenticationError("You don't have permission to do that.")
|
throw new AuthenticationError("You don't have permission to do that.")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (!hasRole({ roles })) {
|
||||||
typeof roles !== 'undefined' &&
|
|
||||||
typeof roles === 'string' &&
|
|
||||||
!context.currentUser.roles?.includes(roles)
|
|
||||||
) {
|
|
||||||
throw new ForbiddenError("You don't have access to do that.")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
typeof roles !== 'undefined' &&
|
|
||||||
Array.isArray(roles) &&
|
|
||||||
!context.currentUser.roles?.some((role) => roles.includes(role))
|
|
||||||
) {
|
|
||||||
throw new ForbiddenError("You don't have access to do that.")
|
throw new ForbiddenError("You don't have access to do that.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
"@redwoodjs/forms": "^0.37.4",
|
"@redwoodjs/forms": "^0.37.4",
|
||||||
"@redwoodjs/router": "^0.37.4",
|
"@redwoodjs/router": "^0.37.4",
|
||||||
"@redwoodjs/web": "^0.37.4",
|
"@redwoodjs/web": "^0.37.4",
|
||||||
"netlify-identity-widget": "^1.9.1",
|
"netlify-identity-widget": "^1.9.2",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2"
|
"react-dom": "^17.0.2"
|
||||||
|
|||||||
@@ -13764,10 +13764,10 @@ nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61"
|
resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61"
|
||||||
integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==
|
integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==
|
||||||
|
|
||||||
netlify-identity-widget@^1.9.1:
|
netlify-identity-widget@^1.9.2:
|
||||||
version "1.9.1"
|
version "1.9.2"
|
||||||
resolved "https://registry.yarnpkg.com/netlify-identity-widget/-/netlify-identity-widget-1.9.1.tgz#9e716c4b92b9f0cc041074eb86fc962f35295b46"
|
resolved "https://registry.yarnpkg.com/netlify-identity-widget/-/netlify-identity-widget-1.9.2.tgz#4339c9155fc4c2570ae3ddd61825d952b574b02e"
|
||||||
integrity sha512-9oIWjwUSdRk3SkREcZNjZaVuDDx9T/wSIXZNQsQeY4qoXic/FiXVEGgu2RU3IuA4OI3L2652xY1o+PpS03Ugaw==
|
integrity sha512-IbS1JHhs7BflCCvp3C9f6tmNSZqbyBhZ4Gs5+Qxt4IlPybTOVv0PqJ4TAsA7uxh1R+oXOAmk0OOMAkEaPYeCtA==
|
||||||
|
|
||||||
new-github-issue-url@0.2.1:
|
new-github-issue-url@0.2.1:
|
||||||
version "0.2.1"
|
version "0.2.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user