소스 검색

added create user form

Tomi Cvetic 5 년 전
부모
커밋
3ec3dfd887
6개의 변경된 파일109개의 추가작업 그리고 2개의 파일을 삭제
  1. 6 0
      backend/datamodel.prisma
  2. 33 0
      backend/index.js
  3. 9 0
      backend/package-lock.json
  4. 2 0
      backend/package.json
  5. 58 0
      frontend/components/UserCreate.js
  6. 1 2
      frontend/lib/withApollo.js

+ 6 - 0
backend/datamodel.prisma

@@ -1,5 +1,11 @@
 # Generic Types
 
+type Meta {
+  id: ID! @unique
+  key: String!
+  value: String!
+}
+
 type User {
   id: ID! @unique
   email: String! @unique

+ 33 - 0
backend/index.js

@@ -1,6 +1,18 @@
+/**
+ * Configure dotenv:
+ * https://www.npmjs.com/package/dotenv
+ * 
+ * Configure file updates with multer:
+ * https://github.com/expressjs/multer
+ * 
+ * Configure CORS for use with localhost.
+ */
+
 require('dotenv').config()
 const { GraphQLServer } = require('graphql-yoga')
 const fileUpload = require('express-fileupload')
+const jwt = require('jsonwebtoken')
+const cookieParser = require('cookie-parser')
 const { resolvers } = require('./src/resolvers')
 const { db } = require('./src/db')
 
@@ -14,6 +26,27 @@ const server = new GraphQLServer({
   })
 })
 
+server.express.use(cookieParser())
+
+server.express.use((req, res, next) => {
+  const { token } = req.cookies
+  if (token) {
+    const { userId } = jwt.verify(token, process.env.APP_SECRET)
+    req.userId = userId
+  }
+  next()
+})
+
+server.express.use(async (req, res, next) => {
+  if (!req.userId) return next()
+  const user = await db.query.user(
+    { where: { id: req.userId } },
+    '{id, email, name}'
+  )
+  req.user = user
+  next()
+})
+
 server.express.use(fileUpload())
 server.express.post('/upload', (req, res) => {
   console.log(req.files)

+ 9 - 0
backend/package-lock.json

@@ -1267,6 +1267,15 @@
       "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
       "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
     },
+    "cookie-parser": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.4.tgz",
+      "integrity": "sha512-lo13tqF3JEtFO7FyA49CqbhaFkskRJ0u/UAiINgrIXeRCY41c88/zxtrECl8AKH3B0hj9q10+h3Kt8I7KlW4tw==",
+      "requires": {
+        "cookie": "0.3.1",
+        "cookie-signature": "1.0.6"
+      }
+    },
     "cookie-signature": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",

+ 2 - 0
backend/package.json

@@ -4,9 +4,11 @@
   "description": "",
   "main": "index.js",
   "dependencies": {
+    "cookie-parser": "^1.4.4",
     "dotenv": "^7.0.0",
     "express-fileupload": "^1.1.4",
     "graphql-yoga": "^1.17.4",
+    "jsonwebtoken": "^8.5.1",
     "prisma": "^1.30.1",
     "prisma-binding": "^2.3.10",
     "prisma-client-lib": "^1.30.1",

+ 58 - 0
frontend/components/UserCreate.js

@@ -0,0 +1,58 @@
+import React from 'react'
+import gql from 'graphql-tag'
+import { Mutation } from 'react-apollo'
+
+const USER_CREATE = gql`
+  mutation USER_CREATE($email: String!, $name: String!, $abbreviation: String!, $password: String!) {
+    createUser(email: $email, name: $name, abbreviation: $abbreviation, password: $password) {
+      id
+      name
+      email
+      abbreviation
+    }
+  }
+`
+
+class UserCreate extends React.Component {
+  state = {
+    name: '',
+    email: '',
+    abbreviation: '',
+    password: ''
+  }
+
+  handleInput = event => {
+    this.setState({ [event.target.name]: event.target.value })
+  }
+
+  render() {
+    <Mutation
+      mutation={USER_CREATE}
+      variables={this.state}
+      refetchQueries={[{ query: USER_CREATE }]}
+    >
+      {(userCreate, { error, loading }) => (
+        <form
+          method="POST"
+          onSubmit={async event => {
+            event.preventDefault()
+            await userCreate()
+            this.setState({ name: '', email: '', abbreviation: '', password: '' })
+          }}
+        >
+          <input type="text" name="name" id="name" value={this.state.name} onChange={this.handleInput} />
+          <label htmlFor="name"></label>
+          <input type="text" name="abbreviation" id="abbreviation" value={this.state.abbreviation} onChange={this.handleInput} />
+          <label htmlFor="abbreviation"></label>
+          <input type="text" name="email" id="email" value={this.state.email} onChange={this.handleInput} />
+          <label htmlFor="email"></label>
+          <input type="password" name="password" id="password" value={this.state.password} onChange={this.handleInput} />
+          <label htmlFor="password"></label>
+          <button type="submit">Create</button>
+        </form>
+      )}
+    </Mutation>
+  }
+}
+
+export default UserCreate

+ 1 - 2
frontend/lib/withApollo.js

@@ -8,13 +8,12 @@
  */
 
 import withApollo from 'next-with-apollo'
-import ApolloClient, { InMemoryCache } from 'apollo-boost'
+import ApolloClient from 'apollo-boost'
 import { endpoint, prodEndpoint } from '../config'
 
 function createClient({ ctx, headers, initialState }) {
   return new ApolloClient({
     uri: process.env.NODE_ENV === 'development' ? endpoint : prodEndpoint,
-    cache: new InMemoryCache().restore(initialState || {}),
     request: operation => {
       operation.setContext({
         fetchOptions: {