· 4 years ago · Apr 12, 2021, 06:08 AM
1import express from 'express';
2import cors from 'cors'
3import User from './class/User';
4import db from './database'
5import { ApolloServer, gql } from 'apollo-server-micro';
6import {UserInputError } from 'apollo-server-express';
7import jwt from 'jsonwebtoken';
8import bcrypt from 'bcrypt'
9
10
11const typeDefs = gql`
12 type Query {
13 users: [User!]!
14 user(username: String!): User
15 }
16
17 type User {
18 username: String
19 employee_id: String
20 shop_code: String
21 emp_type_id: Int
22 period_daily: String
23 period_month: String
24 salt: String
25 pwd: String
26 firstname_th: String
27 lastname_th: String
28 firstname_en: String
29 lastname_en: String
30 phone_number: String
31 user_status: String
32 }
33 input addUserInput{
34 username: String!
35 employee_id: String!
36 shop_code: String
37 emp_type_id: Int!
38 period_daily: String
39 period_month: String
40 salt: String!
41 pwd: String!
42 firstname_th: String!
43 lastname_th: String!
44 firstname_en: String!
45 lastname_en: String!
46 phone_number: String
47 user_status: String!
48}
49type AuthToken {
50 token: String!
51}
52
53 type Mutation {
54 addUser(input : addUserInput!): User
55 updateUser(username: String!,input : addUserInput!): User
56 deleteUser(username: String!): User
57 login (username: String!, pwd: String!): AuthToken
58 }
59`;
60
61const resolvers = {
62 Query: {
63 users: async(_parent, args, _context) => {
64 console.log("TEST")
65 console.log(db
66 .select("*")
67 .from("user_profile")
68 .orderBy("username","asc")
69 .limit(Math.min(args.first, 50))
70 .offset(args.skip)
71 .toSQL())
72 return db
73 .select("*")
74 .from("user_profile")
75 .orderBy("username","asc")
76 .limit(Math.min(args.first, 50))
77 .offset(args.skip);
78
79 },
80 user: async(_parent,{username}, _context) => {
81 console.log("TEST")
82 console.log(db
83 .select("*")
84 .from("user_profile")
85 .where({username})
86 .toSQL())
87 return db
88 .select("*")
89 .table("user_profile")
90 .where({username})
91 .first()
92
93 }
94 },
95 Mutation: {
96 addUser: async (parent,{input} ,context) => {
97 let user : User
98 const saltRounds = 10;
99 input.salt = bcrypt.genSaltSync(saltRounds);
100 try{
101 console.log("Test")
102 console.log("salt : "+ input.salt)
103 input.pwd = bcrypt.hashSync(input.pwd, input.salt);
104 console.log("password : "+input.pwd)
105 console.log({...input})
106 console.log(db('user_profile').insert({...input}).toSQL())
107 user= await db('user_profile').insert({...input})
108
109 }catch(err){
110 throw new UserInputError("Username is duplicated",{
111 invalidArgs: Object.keys({input}),
112
113 });
114 //console.log(err)
115 }
116 db.destroy()
117 return user;
118 },
119
120 updateUser: async (parent,{ username,input },ctx)=>{
121 let user : User
122 try{
123 console.log("Update")
124 console.log({username})
125 console.log({input})
126 console.log(db('user_profile').where({username}).update({...input}).toSQL())
127 user = await db('user_profile')
128 .where({username})
129 .update({...input})
130 }catch(err){
131 throw new UserInputError("Update user error",{
132 invalidArgs: Object.keys({input}),
133 });
134 }
135 db.destroy()
136 return user;
137 },
138 deleteUser :async (parent,{username},ctx)=>{
139 let user : User
140 try{
141 console.log("Delete")
142 console.log({username})
143 console.log(db('user_profile')
144 .where({username})
145 .del().toSQL())
146
147 user = await db('user_profile')
148 .where({username})
149 .del()
150 db.destroy()
151 return user
152 }catch(err){
153 throw new UserInputError("Delete user error",{
154 invalidArgs: Object.keys({username}),
155 });
156 //console.log(err)
157 }
158 },
159 login :async (parent,{username,pwd},ctx)=>{
160 let hash
161 let token
162 let verifySalt
163 let verifyPwd
164 try{
165 console.log("Login")
166 console.log("username:"+username)
167 console.log("pwd:"+pwd)
168 const options = {
169 maxAge: 1000 * 60 * 60 *24 , //expires in 1 Day
170 httpOnly: true, // client can't get cookie by script
171 secure: true, // only transfer over https
172 sameSite: true, // only sent for requests to the same FQDN as the domain in the cookie
173 }
174 await db('user_profile').where({username: username})
175 .first()
176 .then((row) => {
177 verifyPwd = row.pwd
178 verifySalt = row.salt
179
180 console.log("verifySalt:"+verifySalt)
181 console.log("verifyPwd:"+verifyPwd)
182
183 bcrypt.hash(pwd, verifySalt, (err, hash) =>{ // Salt + Hash
184 console.log("hash: "+hash)
185 //bcrypt.compare(hash, verifyPwd,(err, result) =>{
186 bcrypt.compare(pwd, verifyPwd,(err, result) =>{
187 console.log("result:"+result)
188 if (result) {
189 console.log("Password matches!")
190 console.log("username : ",username)
191 console.log("SECRET Key : ",process.env.JWT_SECRET)
192 console.log("Token Login : ", jwt.sign({username: username} , process.env.JWT_SECRET, {
193 expiresIn: '1d',
194 algorithm: 'HS256',
195 }))
196 console.log('==== ctx')
197 console.log(ctx)
198 /*const token = jwt.sign({ username: username }, process.env.JWT_SECRET, {
199 expiresIn: '1d',
200 algorithm: 'HS256',
201 })*/
202 // ctx: ({ req,username }) => {
203
204 console.log("username : ", username)
205 const token = jwt.sign({ username: username }, process.env.JWT_SECRET, {
206 expiresIn: '1d',
207 algorithm: 'HS256',
208 })
209
210 const options = {
211 maxAge: 1000 * 60 * 60 *24 , //expires in 24 hours
212 httpOnly: true, // client can't get cookie by script
213 secure: true, // only transfer over https
214 sameSite: true, // only sent for requests to the same FQDN as the domain in the cookie
215 }
216 //ctx.req.cookie('token', token, options)
217
218 // }
219
220
221 } else {
222 console.log("Password mismatch!")
223 return "Password mismatch!"
224 }
225 })
226 })
227 })
228
229 }catch(err){
230 throw new UserInputError("Authentication failed",{
231 invalidArgs: Object.keys({username}),
232 });
233 //console.log(err)
234 }
235 }
236 }
237}
238
239const apolloServer = new ApolloServer({
240 typeDefs,
241 resolvers,
242 context: ({ req,res }) => {
243 return {
244 //user,
245 ...req,
246 ...res,
247 db
248 };
249 },
250 });
251
252
253const app = express();
254
255
256const corsOptions = {
257 origin(origin, callback) {
258 callback(null, true);
259 },
260 credentials: true
261};
262
263app.use( cors(corsOptions) );
264
265
266
267var allowCrossDomain = function(req, res, next) {
268 res.header('Access-Control-Allow-Origin', '*');
269 res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
270 res.header('Access-Control-Allow-Headers', 'Content-Type,token');
271 next();
272}
273app.use(allowCrossDomain);
274
275const handler = apolloServer.createHandler({path: '/api/graphql'})
276
277export const config = {
278 api: {
279 bodyParser: false,
280 }
281 }
282
283 export default handler