MinsoftK
This diff is collapsed. Click to expand it.
......@@ -20,7 +20,9 @@
"graphql-tools": "^4.0.7",
"graphql-yoga": "^1.18.3",
"jsonwebtoken": "^8.5.1",
"merge-graphql-schemas": "^1.7.7"
"merge-graphql-schemas": "^1.7.7",
"nodemailer": "^6.4.6",
"nodemailer-sendgrid-transport": "^0.2.0"
},
"devDependencies": {
"@babel/core": "^7.9.0",
......
......@@ -14,7 +14,8 @@ model User {
email String @unique
password String
name String
loginSecret String?
emailSecret String?
phoneSecret String?
bio String?
rooms Room[] @relation(references: [id])
messages Message[]
......
import { prisma } from "../../../utils";
export default {
Mutation: {
confirmSecretKey: async (_, args) => {},
},
};
import { prisma } from "../../../utils";
import { prisma, generateToken } from "../../../utils";
import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken";
export default {
Mutation: {
......@@ -16,12 +15,7 @@ export default {
password: encryptPw,
},
});
const token = jwt.sign(
{
id: user.id,
},
process.env.JWT_SECRET
);
const token = generateToken(user.id);
return { token, user };
},
},
......
type Query {
findEmail(secret: String!): User!
}
import { prisma } from "../../../utils";
export default {
Mutation: {
requestSecretKey: async (_, args, { request }) => {
const { email } = args;
Query: {
findEmail: async (_, args) => {
const { secret } = args;
},
},
};
......
type Mutation {
confirmSecretKey(secret: String!, email: String!): String!
requestEmailSecret(email: String!): Boolean!
}
......
import { prisma, generateSecret, sendSecretMail } from "../../../utils";
import bcrypt from "bcryptjs";
export default {
Mutation: {
requestEmailSecret: async (_, args) => {
const { email } = args;
const emailSecret = generateSecret();
const encryptSecret = await bcrypt.hash(emailSecret, 10);
try {
await sendSecretMail(email, emailSecret);
await prisma.user.update({
where: {
email,
},
data: {
emailSecret: encryptSecret,
},
});
return true;
} catch (error) {
console.log(error);
return false;
}
},
},
};
type Mutation {
requestSecretKey(email: String!): Boolean!
}
type Mutation {
resetPassword(
secret: String!
email: String!
passwordOne: String!
passwordTwo: String!
): User!
}
import { prisma } from "../../../utils";
import bcrypt from "bcryptjs";
export default {
Mutation: {
resetPassword: async (_, args) => {
const { secret, email, passwordOne, passwordTwo } = args;
const user = await prisma.user.findOne({
where: {
email,
},
});
const encryptSecret = await bcrypt.hash(user.emailSecret, 10);
if (encryptSecret !== secret) {
throw new Error(
"not vaild secret value!, input another value or resend email"
);
} else {
if (passwordOne !== passwordTwo) {
// For check new password is right, the two things must be same.
throw new Error("the two password don't match each other, try again");
} else {
await prisma.user.update({
where: {
email,
},
data: {
emailSecret: "",
password: passwordOne,
},
});
}
return user;
}
},
},
};
......@@ -4,10 +4,12 @@ type User {
name: String
email: String!
password: String
loginSecret: String
emailSecret: String
phoneSecret: String
bio: String
rooms: [Room]
createdAt: String
messages: [Message]
}
type Room {
......
import jwt from "jsonwebtoken";
import { PrismaClient } from "@prisma/client";
import { nouns, adjectives } from "./words";
import jwt from "jsonwebtoken";
import nodemailer from "nodemailer";
import sgTransport from "nodemailer-sendgrid-transport";
export const prisma = new PrismaClient();
......@@ -12,3 +15,31 @@ export const getUserId = (context) => {
}
throw new Error("There is no vaild user");
};
export const generateSecret = () => {
const randomNumber = Math.floor(Math.random() * adjectives.length);
return `${adjectives[randomNumber]} ${nouns[randomNumber]}`;
};
const sendEmail = (email) => {
const options = {
auth: {
api_user: process.env.SENDGRID_USERNAME,
api_password: process.env.SENDGRID_PASSWORD,
},
};
const client = nodemailer.createTransport(sgTransport(options));
return client.sendMail(email);
};
export const sendSecretMail = (address, emailSecret, value) => {
const email = {
from: "vel1024@khu.ac.kr",
to: address,
subject: `Authentication key for forgotten ${value}`,
html: `Hello, This is khuchat, authentication key is <b>${emailSecret}</b>, copy and paste it, Thanks.`,
};
return sendEmail(email);
};
export const generateToken = (id) => jwt.sign({ id }, process.env.JWT_SECRET);
......
export const adjectives = [
"languid",
"expensive",
"careful",
"feeble",
"inconclusive",
"damp",
"obscene",
"optimal",
"learned",
"measly",
"silent",
"absurd",
"hypnotic",
"smart",
"horrible",
"deep",
"grotesque",
"rigid",
"sweltering",
"quirky",
"pointless",
"spiffy",
"cheap",
"psychotic",
"possible",
"burly",
"huge",
"tranquil",
"impolite",
"clear",
"groovy",
"royal",
"envious",
"voracious",
"substantial",
"gusty",
"absorbing",
"wealthy",
"fancy",
"ultra",
"giant",
"harmonious",
"nauseating",
"literate",
"friendly",
"panicky",
"utopian",
"happy",
"gaudy",
"direful",
"descriptive",
"better",
"ambiguous",
"momentous",
"obsequious",
"secret",
"clever",
"far",
"temporary",
"unable",
"normal",
"imported",
"three",
"five",
"petite",
"natural",
"early",
"profuse",
"flimsy",
"bustling",
"scrawny",
"present",
"gruesome",
"cut",
"fantastic",
"grandiose",
"second-hand",
"noiseless",
"craven",
"grubby",
"vengeful",
"tiny",
"wiry",
"auspicious",
"dull",
"quiet",
"terrific",
"furry",
"crooked",
"wholesale",
"panoramic",
"forgetful",
"gamy",
"victorious",
"special",
"neighborly",
"useful",
"chubby",
"probable",
"abnormal",
];
export const nouns = [
"rat",
"start",
"icicle",
"hobbies",
"books",
"dress",
"board",
"scale",
"cattle",
"quince",
"cabbage",
"chance",
"attack",
"linen",
"swing",
"skin",
"channel",
"discovery",
"window",
"watch",
"collar",
"creature",
"fall",
"rod",
"skirt",
"trousers",
"guitar",
"pest",
"middle",
"holiday",
"invention",
"pump",
"morning",
"reaction",
"wash",
"cloth",
"hydrant",
"committee",
"meeting",
"star",
"pigs",
"bikes",
"plant",
"stomach",
"transport",
"hole",
"library",
"tank",
"hands",
"offer",
"slip",
"chicken",
"sand",
"wilderness",
"sweater",
"frogs",
"basket",
"flesh",
"cook",
"girl",
"queen",
"nut",
"force",
"laborer",
"basin",
"lumber",
"mine",
"mountain",
"insect",
"store",
"experience",
"credit",
"meat",
"taste",
"iron",
"regret",
"sleep",
"notebook",
"powder",
"fuel",
"lace",
"volleyball",
"look",
"ticket",
"place",
"digestion",
"point",
"crook",
"train",
"judge",
"time",
"truck",
"record",
"sheet",
"join",
"achiever",
"spring",
"death",
"potato",
"liquid",
];