Kurt/rw 37 upgrade (#566)

* Update readme

* Upgrade redwood to 0.37.x
This commit was merged in pull request #566.
This commit is contained in:
Kurt Hutten
2021-10-20 14:10:19 +11:00
committed by GitHub
parent e26beda598
commit 219f341972
24 changed files with 5145 additions and 5549 deletions

View File

@@ -3,7 +3,8 @@
"version": "0.0.0",
"private": true,
"dependencies": {
"@redwoodjs/api": "^0.36.4",
"@redwoodjs/api": "^0.37.5",
"@redwoodjs/graphql-server": "^0.37.5",
"@sentry/node": "^6.5.1",
"axios": "^0.21.1",
"cloudinary": "^1.23.0",

View File

@@ -0,0 +1,18 @@
import { mockRedwoodDirective, getDirectiveName } from '@redwoodjs/testing/api'
import requireAuth from './requireAuth'
describe('requireAuth directive', () => {
it('declares the directive sdl as schema, with the correct name', () => {
expect(requireAuth.schema).toBeTruthy()
expect(getDirectiveName(requireAuth.schema)).toBe('requireAuth')
})
it('requireAuth has stub implementation. Should not throw when current user', () => {
// If you want to set values in context, pass it through e.g.
// mockRedwoodDirective(requireAuth, { context: { currentUser: { id: 1, name: 'Lebron McGretzky' } }})
const mockExecution = mockRedwoodDirective(requireAuth, { context: {} })
expect(mockExecution).not.toThrowError()
})
})

View File

@@ -0,0 +1,22 @@
import gql from 'graphql-tag'
import { createValidatorDirective } from '@redwoodjs/graphql-server'
import { requireAuth as applicationRequireAuth } from 'src/lib/auth'
export const schema = gql`
"""
Use to check whether or not a user is authenticated and is associated
with an optional set of roles.
"""
directive @requireAuth(roles: [String]) on FIELD_DEFINITION
`
const validate = ({ directiveArgs }) => {
const { roles } = directiveArgs
applicationRequireAuth({ roles })
}
const requireAuth = createValidatorDirective(schema, validate)
export default requireAuth

View File

@@ -0,0 +1,10 @@
import { getDirectiveName } from '@redwoodjs/testing/api'
import skipAuth from './skipAuth'
describe('skipAuth directive', () => {
it('declares the directive sdl as schema, with the correct name', () => {
expect(skipAuth.schema).toBeTruthy()
expect(getDirectiveName(skipAuth.schema)).toBe('skipAuth')
})
})

View File

@@ -0,0 +1,16 @@
import gql from 'graphql-tag'
import { createValidatorDirective } from '@redwoodjs/graphql-server'
export const schema = gql`
"""
Use to skip authentication checks and allow public access.
"""
directive @skipAuth on FIELD_DEFINITION
`
const skipAuth = createValidatorDirective(schema, () => {
return
})
export default skipAuth

View File

@@ -15,7 +15,7 @@ You'll need to have Docker installed
Because of the way the docker containers to be deployed as lambdas on aws are somewhat specialised for the purpose we're using `docker-compose` to spin one up for each function/endpoint. So we've added a aws-emulation layer
The docker build relies on a git ignored file, the aws-lambda-rie. [Download it](https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/download/v1.0/aws-lambda-rie), then put it into `app/api/src/docker/common/`. alternatively you can put this download into the DockerFiles by reading the instructions at around line 29 of the DockerFiles (`app/api/src/docker/openscad/Dockerfile` & `app/api/src/docker/cadquery/Dockerfile`). However this will mean slower build times as it will need download this 14mb file every build.
The docker build relies on a git ignored file, the aws-lambda-rie. [Download it](https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/download/v1.0/aws-lambda-rie), then put it into `app/api/src/docker/common/`. Alternatively you can put this download into the DockerFiles by reading the instructions at around line 29 of the DockerFiles (`app/api/src/docker/openscad/Dockerfile` & `app/api/src/docker/cadquery/Dockerfile`). However this will mean slower build times as it will need download this 14mb file every build.
Run

View File

@@ -1,12 +1,9 @@
import {
createGraphQLHandler,
makeMergedSchema,
makeServices,
} from '@redwoodjs/api'
import { createGraphQLHandler } from '@redwoodjs/graphql-server'
import { createSentryApolloPlugin } from 'src/lib/sentry'
import { logger } from 'src/lib/logger'
import schemas from 'src/graphql/**/*.{js,ts}'
import directives from 'src/directives/**/*.{js,ts}'
import sdls from 'src/graphql/**/*.sdl.{js,ts}'
import services from 'src/services/**/*.{js,ts}'
import { getCurrentUser } from 'src/lib/auth'
@@ -15,11 +12,11 @@ import { db } from 'src/lib/db'
export const handler = createGraphQLHandler({
loggerConfig: { logger, options: {} },
getCurrentUser,
schema: makeMergedSchema({
schemas,
services: makeServices({ services }),
}),
directives,
sdls,
services,
plugins: [createSentryApolloPlugin()],
onException: () => {
// Disconnect from your database with an unhandled exception.
db.$disconnect()

View File

@@ -11,9 +11,10 @@ export const schema = gql`
}
type Query {
projectReactions: [ProjectReaction!]!
projectReaction(id: String!): ProjectReaction
projectReactions: [ProjectReaction!]! @skipAuth
projectReaction(id: String!): ProjectReaction @skipAuth
projectReactionsByProjectId(projectId: String!): [ProjectReaction!]!
@skipAuth
}
input ToggleProjectReactionInput {
@@ -30,10 +31,11 @@ export const schema = gql`
type Mutation {
toggleProjectReaction(input: ToggleProjectReactionInput!): ProjectReaction!
@requireAuth
updateProjectReaction(
id: String!
input: UpdateProjectReactionInput!
): ProjectReaction!
deleteProjectReaction(id: String!): ProjectReaction!
): ProjectReaction! @requireAuth
deleteProjectReaction(id: String!): ProjectReaction! @requireAuth
}
`

View File

@@ -11,8 +11,8 @@ export const schema = gql`
}
type Query {
comments: [Comment!]!
comment(id: String!): Comment
comments: [Comment!]! @skipAuth
comment(id: String!): Comment @skipAuth
}
input CreateCommentInput {
@@ -28,8 +28,9 @@ export const schema = gql`
}
type Mutation {
createComment(input: CreateCommentInput!): Comment!
createComment(input: CreateCommentInput!): Comment! @requireAuth
updateComment(id: String!, input: UpdateCommentInput!): Comment!
deleteComment(id: String!): Comment!
@requireAuth
deleteComment(id: String!): Comment! @requireAuth
}
`

View File

@@ -15,6 +15,6 @@ export const schema = gql`
}
type Mutation {
sendAllUsersEmail(input: Email!): EmailResponse!
sendAllUsersEmail(input: Email!): EmailResponse! @requireAuth
}
`

View File

@@ -26,9 +26,10 @@ export const schema = gql`
}
type Query {
projects(userName: String): [Project!]!
project(id: String!): Project
projects(userName: String): [Project!]! @skipAuth
project(id: String!): Project @skipAuth
projectByUserAndTitle(userName: String!, projectTitle: String!): Project
@skipAuth
}
input CreateProjectInput {
@@ -55,14 +56,15 @@ export const schema = gql`
}
type Mutation {
createProject(input: CreateProjectInput!): Project!
forkProject(input: ForkProjectInput!): Project!
createProject(input: CreateProjectInput!): Project! @requireAuth
forkProject(input: ForkProjectInput!): Project! @requireAuth
updateProject(id: String!, input: UpdateProjectInput!): Project!
@requireAuth
updateProjectImages(
id: String!
mainImage64: String
socialCard64: String
): Project!
deleteProject(id: String!): Project!
): Project! @requireAuth
deleteProject(id: String!): Project! @requireAuth
}
`

View File

@@ -10,7 +10,7 @@ export const schema = gql`
}
type Query {
socialCards: [SocialCard!]!
socialCard(id: String!): SocialCard
socialCards: [SocialCard!]! @skipAuth
socialCard(id: String!): SocialCard @skipAuth
}
`

View File

@@ -10,8 +10,8 @@ export const schema = gql`
}
type Query {
subjectAccessRequests: [SubjectAccessRequest!]!
subjectAccessRequest(id: String!): SubjectAccessRequest
subjectAccessRequests: [SubjectAccessRequest!]! @requireAuth
subjectAccessRequest(id: String!): SubjectAccessRequest @requireAuth
}
input CreateSubjectAccessRequestInput {
@@ -29,11 +29,11 @@ export const schema = gql`
type Mutation {
createSubjectAccessRequest(
input: CreateSubjectAccessRequestInput!
): SubjectAccessRequest!
): SubjectAccessRequest! @requireAuth
updateSubjectAccessRequest(
id: String!
input: UpdateSubjectAccessRequestInput!
): SubjectAccessRequest!
deleteSubjectAccessRequest(id: String!): SubjectAccessRequest!
): SubjectAccessRequest! @requireAuth
deleteSubjectAccessRequest(id: String!): SubjectAccessRequest! @requireAuth
}
`

View File

@@ -16,9 +16,9 @@ export const schema = gql`
}
type Query {
users: [User!]!
user(id: String!): User
userName(userName: String!): User
users: [User!]! @requireAuth
user(id: String!): User @skipAuth
userName(userName: String!): User @skipAuth
}
input CreateUserInput {
@@ -38,9 +38,10 @@ export const schema = gql`
}
type Mutation {
createUser(input: CreateUserInput!): User!
updateUser(id: String!, input: UpdateUserInput!): User!
createUser(input: CreateUserInput!): User! @requireAuth
updateUser(id: String!, input: UpdateUserInput!): User! @requireAuth
updateUserByUserName(userName: String!, input: UpdateUserInput!): User!
deleteUser(id: String!): User!
@requireAuth
deleteUser(id: String!): User! @requireAuth
}
`

View File

@@ -1,61 +1,5 @@
// Define what you want `currentUser` to return throughout your app. For example,
// to return a real user from your database, you could do something like:
//
// export const getCurrentUser = async ({ email }) => {
// return await db.user.findUnique({ where: { email } })
// }
//
// If you want to enforce role-based access ...
//
// You'll need to set the currentUser's roles attributes to the
// collection of roles as defined by your app.
//
// This allows requireAuth() on the api side and hasRole() in the useAuth() hook on the web side
// to check if the user is assigned a given role or not.
//
// How you set the currentUser's roles depends on your auth provider and its implementation.
//
// For example, your decoded JWT may store `roles` in it namespaced `app_metadata`:
//
// {
// 'https://example.com/app_metadata': { authorization: { roles: ['admin'] } },
// 'https://example.com/user_metadata': {},
// iss: 'https://app.us.auth0.com/',
// sub: 'email|1234',
// aud: [
// 'https://example.com',
// 'https://app.us.auth0.com/userinfo'
// ],
// iat: 1596481520,
// exp: 1596567920,
// azp: '1l0w6JXXXXL880T',
// scope: 'openid profile email'
// }
//
// The parseJWT utility will extract the roles from decoded token.
//
// The app_medata claim may or may not be namespaced based on the auth provider.
// Note: Auth0 requires namespacing custom JWT claims
//
// Some providers, such as with Auth0, will set roles an authorization
// attribute in app_metadata (namespaced or not):
//
// 'app_metadata': { authorization: { roles: ['publisher'] } }
// 'https://example.com/app_metadata': { authorization: { roles: ['publisher'] } }
//
// Other providers may include roles simply within app_metadata:
//
// 'app_metadata': { roles: ['author'] }
// 'https://example.com/app_metadata': { roles: ['author'] }
//
// And yet other may define roles as a custom claim at the root of the decoded token:
//
// roles: ['admin']
//
// The function `getCurrentUser` should return the user information
// together with a collection of roles to check for role assignment:
import { AuthenticationError, ForbiddenError, parseJWT } from '@redwoodjs/api'
import { AuthenticationError, ForbiddenError } from '@redwoodjs/graphql-server'
import { parseJWT } from '@redwoodjs/api'
/**
* Use requireAuth in your services to check that a user is logged in,
@@ -97,8 +41,24 @@ import { AuthenticationError, ForbiddenError, parseJWT } from '@redwoodjs/api'
* }
* }
*/
export const getCurrentUser = async (decoded, { _token, _type }) => {
return { ...decoded, roles: parseJWT({ decoded }).roles }
export const getCurrentUser = async (
decoded,
{ _token, _type },
{ _event, _context }
) => {
if (!decoded) {
// if no decoded, then never set currentUser
return null
}
const { roles } = parseJWT({ decoded }) // extract and check roles separately
if (roles) {
return { ...decoded, roles }
}
return { ...decoded } // only return when certain you have
// the currentUser properties
}
/**

View File

@@ -1,4 +1,4 @@
import { AuthenticationError, ForbiddenError } from '@redwoodjs/api'
import { AuthenticationError, ForbiddenError } from '@redwoodjs/graphql-server'
import type { Project } from '@prisma/client'
import { db } from 'src/lib/db'

View File

@@ -1,5 +1,5 @@
import { Config, ApolloError } from '@redwoodjs/graphql-server'
import * as Sentry from '@sentry/node'
import { Config, ApolloError } from '@redwoodjs/api'
let sentryInitialized = false
if (process.env.SENTRY_DSN && !sentryInitialized) {

View File

@@ -1,4 +1,4 @@
import { UserInputError } from '@redwoodjs/api'
import { UserInputError } from '@redwoodjs/graphql-server'
import { requireAuth } from 'src/lib/auth'
import { requireOwnership } from 'src/lib/owner'

View File

@@ -1,5 +1,5 @@
import { ResolverArgs } from '@redwoodjs/graphql-server'
import type { Prisma, Project as ProjectType } from '@prisma/client'
import type { ResolverArgs } from '@redwoodjs/api'
import { uploadImage, makeSocialPublicIdServer } from 'src/lib/cloudinary'
import { db } from 'src/lib/db'

View File

@@ -1,5 +1,5 @@
import { ResolverArgs, BeforeResolverSpecType } from '@redwoodjs/graphql-server'
import type { Prisma } from '@prisma/client'
import type { ResolverArgs, BeforeResolverSpecType } from '@redwoodjs/api'
import { db } from 'src/lib/db'
import { requireAuth } from 'src/lib/auth'

View File

@@ -1,10 +1,9 @@
import { UserInputError, ForbiddenError } from '@redwoodjs/graphql-server'
import { db } from 'src/lib/db'
import { requireAuth } from 'src/lib/auth'
import { requireOwnership } from 'src/lib/owner'
import { UserInputError } from '@redwoodjs/api'
import { enforceAlphaNumeric, destroyImage } from 'src/services/helpers'
import type { Prisma } from '@prisma/client'
import { ForbiddenError } from '@redwoodjs/api'
function userNameVerification(userName: string): string {
if (userName.length < 5) {

View File

@@ -12,7 +12,7 @@
"aws-emulate": "nodemon ./api/src/docker/aws-emulator.js"
},
"devDependencies": {
"@redwoodjs/core": "^0.36.4"
"@redwoodjs/core": "^0.37.5"
},
"eslintConfig": {
"extends": "@redwoodjs/eslint-config",

View File

@@ -20,10 +20,10 @@
"@react-three/drei": "^7.3.1",
"@react-three/fiber": "^7.0.5",
"@react-three/postprocessing": "^2.0.5",
"@redwoodjs/auth": "^0.36.4",
"@redwoodjs/forms": "^0.36.4",
"@redwoodjs/router": "^0.36.4",
"@redwoodjs/web": "^0.36.4",
"@redwoodjs/auth": "^0.37.5",
"@redwoodjs/forms": "^0.37.5",
"@redwoodjs/router": "^0.37.5",
"@redwoodjs/web": "^0.37.5",
"@sentry/browser": "^6.5.1",
"@tailwindcss/aspect-ratio": "0.2.1",
"axios": "^0.21.1",
@@ -62,4 +62,4 @@
"raw-loader": "^4.0.2",
"tailwindcss": "^2.2.7"
}
}
}

File diff suppressed because it is too large Load Diff