MinsoftK
This diff is collapsed. Click to expand it.
...@@ -20,7 +20,9 @@ ...@@ -20,7 +20,9 @@
20 "graphql-tools": "^4.0.7", 20 "graphql-tools": "^4.0.7",
21 "graphql-yoga": "^1.18.3", 21 "graphql-yoga": "^1.18.3",
22 "jsonwebtoken": "^8.5.1", 22 "jsonwebtoken": "^8.5.1",
23 - "merge-graphql-schemas": "^1.7.7" 23 + "merge-graphql-schemas": "^1.7.7",
24 + "nodemailer": "^6.4.6",
25 + "nodemailer-sendgrid-transport": "^0.2.0"
24 }, 26 },
25 "devDependencies": { 27 "devDependencies": {
26 "@babel/core": "^7.9.0", 28 "@babel/core": "^7.9.0",
......
...@@ -14,7 +14,8 @@ model User { ...@@ -14,7 +14,8 @@ model User {
14 email String @unique 14 email String @unique
15 password String 15 password String
16 name String 16 name String
17 - loginSecret String? 17 + emailSecret String?
18 + phoneSecret String?
18 bio String? 19 bio String?
19 rooms Room[] @relation(references: [id]) 20 rooms Room[] @relation(references: [id])
20 messages Message[] 21 messages Message[]
......
1 -import { prisma } from "../../../utils";
2 -
3 -export default {
4 - Mutation: {
5 - confirmSecretKey: async (_, args) => {},
6 - },
7 -};
1 -import { prisma } from "../../../utils"; 1 +import { prisma, generateToken } from "../../../utils";
2 import bcrypt from "bcryptjs"; 2 import bcrypt from "bcryptjs";
3 -import jwt from "jsonwebtoken";
4 3
5 export default { 4 export default {
6 Mutation: { 5 Mutation: {
...@@ -16,12 +15,7 @@ export default { ...@@ -16,12 +15,7 @@ export default {
16 password: encryptPw, 15 password: encryptPw,
17 }, 16 },
18 }); 17 });
19 - const token = jwt.sign( 18 + const token = generateToken(user.id);
20 - {
21 - id: user.id,
22 - },
23 - process.env.JWT_SECRET
24 - );
25 return { token, user }; 19 return { token, user };
26 }, 20 },
27 }, 21 },
......
1 +type Query {
2 + findEmail(secret: String!): User!
3 +}
1 import { prisma } from "../../../utils"; 1 import { prisma } from "../../../utils";
2 2
3 export default { 3 export default {
4 - Mutation: { 4 + Query: {
5 - requestSecretKey: async (_, args, { request }) => { 5 + findEmail: async (_, args) => {
6 - const { email } = args; 6 + const { secret } = args;
7 }, 7 },
8 }, 8 },
9 }; 9 };
......
1 type Mutation { 1 type Mutation {
2 - confirmSecretKey(secret: String!, email: String!): String! 2 + requestEmailSecret(email: String!): Boolean!
3 } 3 }
......
1 +import { prisma, generateSecret, sendSecretMail } from "../../../utils";
2 +import bcrypt from "bcryptjs";
3 +
4 +export default {
5 + Mutation: {
6 + requestEmailSecret: async (_, args) => {
7 + const { email } = args;
8 + const emailSecret = generateSecret();
9 + const encryptSecret = await bcrypt.hash(emailSecret, 10);
10 + try {
11 + await sendSecretMail(email, emailSecret);
12 + await prisma.user.update({
13 + where: {
14 + email,
15 + },
16 + data: {
17 + emailSecret: encryptSecret,
18 + },
19 + });
20 + return true;
21 + } catch (error) {
22 + console.log(error);
23 + return false;
24 + }
25 + },
26 + },
27 +};
1 -type Mutation {
2 - requestSecretKey(email: String!): Boolean!
3 -}
1 +type Mutation {
2 + resetPassword(
3 + secret: String!
4 + email: String!
5 + passwordOne: String!
6 + passwordTwo: String!
7 + ): User!
8 +}
1 +import { prisma } from "../../../utils";
2 +import bcrypt from "bcryptjs";
3 +
4 +export default {
5 + Mutation: {
6 + resetPassword: async (_, args) => {
7 + const { secret, email, passwordOne, passwordTwo } = args;
8 + const user = await prisma.user.findOne({
9 + where: {
10 + email,
11 + },
12 + });
13 + const encryptSecret = await bcrypt.hash(user.emailSecret, 10);
14 + if (encryptSecret !== secret) {
15 + throw new Error(
16 + "not vaild secret value!, input another value or resend email"
17 + );
18 + } else {
19 + if (passwordOne !== passwordTwo) {
20 + // For check new password is right, the two things must be same.
21 + throw new Error("the two password don't match each other, try again");
22 + } else {
23 + await prisma.user.update({
24 + where: {
25 + email,
26 + },
27 + data: {
28 + emailSecret: "",
29 + password: passwordOne,
30 + },
31 + });
32 + }
33 + return user;
34 + }
35 + },
36 + },
37 +};
...@@ -4,10 +4,12 @@ type User { ...@@ -4,10 +4,12 @@ type User {
4 name: String 4 name: String
5 email: String! 5 email: String!
6 password: String 6 password: String
7 - loginSecret: String 7 + emailSecret: String
8 + phoneSecret: String
8 bio: String 9 bio: String
9 rooms: [Room] 10 rooms: [Room]
10 createdAt: String 11 createdAt: String
12 + messages: [Message]
11 } 13 }
12 14
13 type Room { 15 type Room {
......
1 -import jwt from "jsonwebtoken";
2 import { PrismaClient } from "@prisma/client"; 1 import { PrismaClient } from "@prisma/client";
2 +import { nouns, adjectives } from "./words";
3 +import jwt from "jsonwebtoken";
4 +import nodemailer from "nodemailer";
5 +import sgTransport from "nodemailer-sendgrid-transport";
3 6
4 export const prisma = new PrismaClient(); 7 export const prisma = new PrismaClient();
5 8
...@@ -12,3 +15,31 @@ export const getUserId = (context) => { ...@@ -12,3 +15,31 @@ export const getUserId = (context) => {
12 } 15 }
13 throw new Error("There is no vaild user"); 16 throw new Error("There is no vaild user");
14 }; 17 };
18 +
19 +export const generateSecret = () => {
20 + const randomNumber = Math.floor(Math.random() * adjectives.length);
21 + return `${adjectives[randomNumber]} ${nouns[randomNumber]}`;
22 +};
23 +
24 +const sendEmail = (email) => {
25 + const options = {
26 + auth: {
27 + api_user: process.env.SENDGRID_USERNAME,
28 + api_password: process.env.SENDGRID_PASSWORD,
29 + },
30 + };
31 + const client = nodemailer.createTransport(sgTransport(options));
32 + return client.sendMail(email);
33 +};
34 +
35 +export const sendSecretMail = (address, emailSecret, value) => {
36 + const email = {
37 + from: "vel1024@khu.ac.kr",
38 + to: address,
39 + subject: `Authentication key for forgotten ${value}`,
40 + html: `Hello, This is khuchat, authentication key is <b>${emailSecret}</b>, copy and paste it, Thanks.`,
41 + };
42 + return sendEmail(email);
43 +};
44 +
45 +export const generateToken = (id) => jwt.sign({ id }, process.env.JWT_SECRET);
......
1 +export const adjectives = [
2 + "languid",
3 + "expensive",
4 + "careful",
5 + "feeble",
6 + "inconclusive",
7 + "damp",
8 + "obscene",
9 + "optimal",
10 + "learned",
11 + "measly",
12 + "silent",
13 + "absurd",
14 + "hypnotic",
15 + "smart",
16 + "horrible",
17 + "deep",
18 + "grotesque",
19 + "rigid",
20 + "sweltering",
21 + "quirky",
22 + "pointless",
23 + "spiffy",
24 + "cheap",
25 + "psychotic",
26 + "possible",
27 + "burly",
28 + "huge",
29 + "tranquil",
30 + "impolite",
31 + "clear",
32 + "groovy",
33 + "royal",
34 + "envious",
35 + "voracious",
36 + "substantial",
37 + "gusty",
38 + "absorbing",
39 + "wealthy",
40 + "fancy",
41 + "ultra",
42 + "giant",
43 + "harmonious",
44 + "nauseating",
45 + "literate",
46 + "friendly",
47 + "panicky",
48 + "utopian",
49 + "happy",
50 + "gaudy",
51 + "direful",
52 + "descriptive",
53 + "better",
54 + "ambiguous",
55 + "momentous",
56 + "obsequious",
57 + "secret",
58 + "clever",
59 + "far",
60 + "temporary",
61 + "unable",
62 + "normal",
63 + "imported",
64 + "three",
65 + "five",
66 + "petite",
67 + "natural",
68 + "early",
69 + "profuse",
70 + "flimsy",
71 + "bustling",
72 + "scrawny",
73 + "present",
74 + "gruesome",
75 + "cut",
76 + "fantastic",
77 + "grandiose",
78 + "second-hand",
79 + "noiseless",
80 + "craven",
81 + "grubby",
82 + "vengeful",
83 + "tiny",
84 + "wiry",
85 + "auspicious",
86 + "dull",
87 + "quiet",
88 + "terrific",
89 + "furry",
90 + "crooked",
91 + "wholesale",
92 + "panoramic",
93 + "forgetful",
94 + "gamy",
95 + "victorious",
96 + "special",
97 + "neighborly",
98 + "useful",
99 + "chubby",
100 + "probable",
101 + "abnormal",
102 +];
103 +
104 +export const nouns = [
105 + "rat",
106 + "start",
107 + "icicle",
108 + "hobbies",
109 + "books",
110 + "dress",
111 + "board",
112 + "scale",
113 + "cattle",
114 + "quince",
115 + "cabbage",
116 + "chance",
117 + "attack",
118 + "linen",
119 + "swing",
120 + "skin",
121 + "channel",
122 + "discovery",
123 + "window",
124 + "watch",
125 + "collar",
126 + "creature",
127 + "fall",
128 + "rod",
129 + "skirt",
130 + "trousers",
131 + "guitar",
132 + "pest",
133 + "middle",
134 + "holiday",
135 + "invention",
136 + "pump",
137 + "morning",
138 + "reaction",
139 + "wash",
140 + "cloth",
141 + "hydrant",
142 + "committee",
143 + "meeting",
144 + "star",
145 + "pigs",
146 + "bikes",
147 + "plant",
148 + "stomach",
149 + "transport",
150 + "hole",
151 + "library",
152 + "tank",
153 + "hands",
154 + "offer",
155 + "slip",
156 + "chicken",
157 + "sand",
158 + "wilderness",
159 + "sweater",
160 + "frogs",
161 + "basket",
162 + "flesh",
163 + "cook",
164 + "girl",
165 + "queen",
166 + "nut",
167 + "force",
168 + "laborer",
169 + "basin",
170 + "lumber",
171 + "mine",
172 + "mountain",
173 + "insect",
174 + "store",
175 + "experience",
176 + "credit",
177 + "meat",
178 + "taste",
179 + "iron",
180 + "regret",
181 + "sleep",
182 + "notebook",
183 + "powder",
184 + "fuel",
185 + "lace",
186 + "volleyball",
187 + "look",
188 + "ticket",
189 + "place",
190 + "digestion",
191 + "point",
192 + "crook",
193 + "train",
194 + "judge",
195 + "time",
196 + "truck",
197 + "record",
198 + "sheet",
199 + "join",
200 + "achiever",
201 + "spring",
202 + "death",
203 + "potato",
204 + "liquid",
205 +];