sdy
Showing 112 changed files with 0 additions and 1592 deletions
*.xlsx
.env
\ No newline at end of file
# Capstone design
1st semester capstone design project
Subject : Making website in order to practice latest web technologies
sub-subject : making chat site using JS
# Schedule
- 4/6 ~ 4/12
- [x] Set development environment
(tech : react.js, react hooks, styled-components, GraphQL, Prisma, Apollo, AWS, Docker)
- 4/13 ~ 4/19
- [x] login, sign up (using JWT, sendGrid), Create Docker-compose
- 4/20 ~ 4/26
- [X] Find ID, PW
- 4/27 ~ 5/3
- [X] Make chat room (using GraphQL's subscription)
- 5/4 ~ 5/10
- [X] Mid-term exam, Debugging
- 5/11 ~ 5/17
- [X] Plan chat category and make code
- 5/18 ~ 5/24
- [X] Debugging for code created in 6th week's plan
- 5/25 ~ 5/31
- [X] Plan a matching strategy for random chat
- 6/1 ~ 6/7
- [X] Make a code based on the matching plan created in 8th week's plan
- 6/8 ~ 6/14
- [X] Debugging for whole codes in our project, and meeting with mento
{
"presets": ["@babel/preset-env"]
}
node_modules
\ No newline at end of file
# node_modules
node_modules
.env
note.txt
linux.txt
\ No newline at end of file
FROM node:12.16.2
RUN npm i -g @prisma/cli
RUN mkdir /app
WORKDIR /app
COPY package*.json ./
COPY prisma ./prisma/
RUN npm install && npx prisma generate
CMD ["npm","start"]
COPY . .
\ No newline at end of file
# Capstone design
1st semester capstone design project
Subject : Making website in order to practice latest web technologies
sub-subject : making chat site using JS
# Schedule
- 4/6 ~ 4/12
- [x] Set development environment
(tech : react.js, react hooks, styled-components, GraphQL, Prisma, Apollo, AWS, Docker)
- 4/13 ~ 4/19
- [x] login, sign up (using JWT, sendGrid), Create Docker-compose
- 4/20 ~ 4/26
- [ ] Find ID, PW
- 4/27 ~ 5/3
- [ ] Make chat room (using GraphQL's subscription)
- 5/4 ~ 5/10
- [ ] Mid-term exam, Debugging
- 5/11 ~ 5/17
- [ ] Plan chat category and make code
- 5/18 ~ 5/24
- [ ] Debugging for code created in 6th week's plan
- 5/25 ~ 5/31
- [ ] Plan a matching strategy for random chat
- 6/1 ~ 6/7
- [ ] Make a code based on the matching plan created in 8th week's plan
- 6/8 ~ 6/14
- [ ] Debugging for whole codes in our project
- 6/15 ~ 6/21
- [ ] Deploy project in AWS amplify
- 6/22 ~ 6/26
- [ ] Final exam, review project
{
"ext": "js graphql"
}
This diff could not be displayed because it is too large.
{
"name": "capstone-back",
"version": "1.0.0",
"description": "1st semester capstone design project",
"scripts": {
"start": "nodemon --exec babel-node src/server.js",
"prisma": "prisma2 studio --experimental"
},
"repository": {
"type": "git",
"url": "git+https://vel1024@bitbucket.org/vel1024/capstone2.git"
},
"author": "sdy, kms",
"license": "ISC",
"homepage": "https://bitbucket.org/vel1024/capstone2#readme",
"dependencies": {
"@prisma/client": "^2.0.0-beta.2",
"bcryptjs": "^2.4.3",
"dotenv": "^8.2.0",
"graphql-tools": "^4.0.7",
"graphql-yoga": "^1.18.3",
"jsonwebtoken": "^8.5.1",
"merge-graphql-schemas": "^1.7.7",
"nodemailer": "^6.4.6",
"nodemailer-sendgrid-transport": "^0.2.0",
"twilio": "^3.42.2"
},
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/node": "^7.8.7",
"@babel/preset-env": "^7.9.0",
"@prisma/cli": "^2.0.0-beta.2",
"morgan": "^1.10.0",
"nodemon": "^2.0.2"
}
}
FROM node:12.16.2
RUN npm i -g @prisma/cli
RUN mkdir /app
WORKDIR /app
COPY ./ ./prisma/
CMD ["prisma", "studio", "--experimental"]
\ No newline at end of file
# Migration `20200419160117-init`
This migration has been generated by sdy at 4/19/2020, 4:01:17 PM.
You can check out the [state of the schema](./schema.prisma) after the migration.
## Database Steps
```sql
CREATE TABLE `chat_schema`.`User` (
`avatarUrl` varchar(191) ,
`bio` varchar(191) ,
`createdAt` datetime DEFAULT CURRENT_TIMESTAMP ,
`email` varchar(191) NOT NULL ,
`id` int NOT NULL AUTO_INCREMENT,
`loginSecret` varchar(191) ,
`name` varchar(191) NOT NULL ,
`password` varchar(191) NOT NULL ,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`Room` (
`id` int NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`Category` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(191) DEFAULT '' ,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`Message` (
`id` int NOT NULL AUTO_INCREMENT,
`senderId` int NOT NULL ,
`text` varchar(191) DEFAULT '' ,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`_RoomToUser` (
`A` int NOT NULL ,
`B` int NOT NULL
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`_CategoryToRoom` (
`A` int NOT NULL ,
`B` int NOT NULL
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE UNIQUE INDEX `User.email` ON `chat_schema`.`User`(`email`)
CREATE UNIQUE INDEX `_RoomToUser_AB_unique` ON `chat_schema`.`_RoomToUser`(`A`,`B`)
CREATE INDEX `_RoomToUser_B_index` ON `chat_schema`.`_RoomToUser`(`B`)
CREATE UNIQUE INDEX `_CategoryToRoom_AB_unique` ON `chat_schema`.`_CategoryToRoom`(`A`,`B`)
CREATE INDEX `_CategoryToRoom_B_index` ON `chat_schema`.`_CategoryToRoom`(`B`)
ALTER TABLE `chat_schema`.`Message` ADD FOREIGN KEY (`senderId`) REFERENCES `chat_schema`.`User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_RoomToUser` ADD FOREIGN KEY (`A`) REFERENCES `chat_schema`.`Room`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_RoomToUser` ADD FOREIGN KEY (`B`) REFERENCES `chat_schema`.`User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_CategoryToRoom` ADD FOREIGN KEY (`A`) REFERENCES `chat_schema`.`Category`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_CategoryToRoom` ADD FOREIGN KEY (`B`) REFERENCES `chat_schema`.`Room`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
DROP TABLE `chat_schema`.`_migration`;
DROP TABLE `chat_schema`.`test`;
```
## Changes
```diff
diff --git schema.prisma schema.prisma
migration ..20200419160117-init
--- datamodel.dml
+++ datamodel.dml
@@ -1,0 +1,41 @@
+generator client {
+ provider = "prisma-client-js"
+ binaryTargets = ["native", "debian-openssl-1.1.x"]
+}
+
+datasource db {
+ provider = "mysql"
+ url = env("DATABASE_URL")
+}
+
+model User {
+ id Int @default(autoincrement()) @id
+ avatarUrl String?
+ email String @unique
+ password String
+ name String
+ loginSecret String?
+ bio String?
+ rooms Room[] @relation(references: [id])
+ messages Message[]
+ createdAt DateTime? @default(now())
+}
+
+model Room {
+ id Int @default(autoincrement()) @id
+ participants User[] @relation(references: [id])
+ categories Category[] @relation(references: [id])
+}
+
+model Category {
+ id Int @default(autoincrement()) @id
+ name String? @default("")
+ rooms Room[] @relation(references: [id])
+}
+
+model Message {
+ id Int @default(autoincrement()) @id
+ text String? @default("")
+ sender User @relation(fields: [senderId], references: [id])
+ senderId Int
+}
```
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "debian-openssl-1.1.x"]
}
datasource db {
provider = "mysql"
url = "***"
}
model User {
id Int @default(autoincrement()) @id
avatarUrl String?
email String @unique
password String
name String
loginSecret String?
bio String?
rooms Room[] @relation(references: [id])
messages Message[]
createdAt DateTime? @default(now())
}
model Room {
id Int @default(autoincrement()) @id
participants User[] @relation(references: [id])
categories Category[] @relation(references: [id])
}
model Category {
id Int @default(autoincrement()) @id
name String? @default("")
rooms Room[] @relation(references: [id])
}
model Message {
id Int @default(autoincrement()) @id
text String? @default("")
sender User @relation(fields: [senderId], references: [id])
senderId Int
}
\ No newline at end of file
# Migration `20200424124259-init`
This migration has been generated by sdy at 4/24/2020, 12:42:59 PM.
You can check out the [state of the schema](./schema.prisma) after the migration.
## Database Steps
```sql
CREATE TABLE `chat_schema`.`User` (
`avatarUrl` varchar(191) ,
`bio` varchar(191) ,
`createdAt` datetime DEFAULT CURRENT_TIMESTAMP ,
`email` varchar(191) NOT NULL ,
`emailSecret` varchar(191) ,
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(191) NOT NULL ,
`password` varchar(191) NOT NULL ,
`phoneNumber` int ,
`phoneSecret` varchar(191) ,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`Room` (
`id` int NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`Category` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(191) DEFAULT '' ,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`Message` (
`id` int NOT NULL AUTO_INCREMENT,
`senderId` int NOT NULL ,
`text` varchar(191) DEFAULT '' ,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`_RoomToUser` (
`A` int NOT NULL ,
`B` int NOT NULL
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`_CategoryToRoom` (
`A` int NOT NULL ,
`B` int NOT NULL
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE UNIQUE INDEX `User.email` ON `chat_schema`.`User`(`email`)
CREATE UNIQUE INDEX `_RoomToUser_AB_unique` ON `chat_schema`.`_RoomToUser`(`A`,`B`)
CREATE INDEX `_RoomToUser_B_index` ON `chat_schema`.`_RoomToUser`(`B`)
CREATE UNIQUE INDEX `_CategoryToRoom_AB_unique` ON `chat_schema`.`_CategoryToRoom`(`A`,`B`)
CREATE INDEX `_CategoryToRoom_B_index` ON `chat_schema`.`_CategoryToRoom`(`B`)
ALTER TABLE `chat_schema`.`Message` ADD FOREIGN KEY (`senderId`) REFERENCES `chat_schema`.`User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_RoomToUser` ADD FOREIGN KEY (`A`) REFERENCES `chat_schema`.`Room`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_RoomToUser` ADD FOREIGN KEY (`B`) REFERENCES `chat_schema`.`User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_CategoryToRoom` ADD FOREIGN KEY (`A`) REFERENCES `chat_schema`.`Category`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_CategoryToRoom` ADD FOREIGN KEY (`B`) REFERENCES `chat_schema`.`Room`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
DROP TABLE `chat_schema`.`_categorytoroom`;
DROP TABLE `chat_schema`.`_migration`;
DROP TABLE `chat_schema`.`_roomtouser`;
DROP TABLE `chat_schema`.`category`;
DROP TABLE `chat_schema`.`message`;
DROP TABLE `chat_schema`.`room`;
DROP TABLE `chat_schema`.`test`;
DROP TABLE `chat_schema`.`user`;
```
## Changes
```diff
diff --git schema.prisma schema.prisma
migration 20200419160117-init..20200424124259-init
--- datamodel.dml
+++ datamodel.dml
@@ -4,18 +4,20 @@
}
datasource db {
provider = "mysql"
- url = "***"
+ url = env("DATABASE_URL")
}
model User {
id Int @default(autoincrement()) @id
avatarUrl String?
email String @unique
password String
name String
- loginSecret String?
+ phoneNumber Int?
+ emailSecret String?
+ phoneSecret String?
bio String?
rooms Room[] @relation(references: [id])
messages Message[]
createdAt DateTime? @default(now())
```
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "debian-openssl-1.1.x"]
}
datasource db {
provider = "mysql"
url = "***"
}
model User {
id Int @default(autoincrement()) @id
avatarUrl String?
email String @unique
password String
name String
phoneNumber Int?
emailSecret String?
phoneSecret String?
bio String?
rooms Room[] @relation(references: [id])
messages Message[]
createdAt DateTime? @default(now())
}
model Room {
id Int @default(autoincrement()) @id
participants User[] @relation(references: [id])
categories Category[] @relation(references: [id])
}
model Category {
id Int @default(autoincrement()) @id
name String? @default("")
rooms Room[] @relation(references: [id])
}
model Message {
id Int @default(autoincrement()) @id
text String? @default("")
sender User @relation(fields: [senderId], references: [id])
senderId Int
}
\ No newline at end of file
{
"version": "0.3.14-fixed",
"steps": [
{
"tag": "CreateField",
"model": "User",
"field": "phoneNumber",
"type": "Int",
"arity": "Optional"
},
{
"tag": "CreateField",
"model": "User",
"field": "emailSecret",
"type": "String",
"arity": "Optional"
},
{
"tag": "CreateField",
"model": "User",
"field": "phoneSecret",
"type": "String",
"arity": "Optional"
},
{
"tag": "DeleteField",
"model": "User",
"field": "loginSecret"
}
]
}
\ No newline at end of file
# IF THERE'S A GIT CONFLICT IN THIS FILE, DON'T SOLVE IT MANUALLY!
# INSTEAD EXECUTE `prisma migrate fix`
# Prisma Migrate lockfile v1
# Read more about conflict resolution here: TODO
20200419160117-init
20200424124259-init
\ No newline at end of file
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "debian-openssl-1.1.x"]
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model User {
id Int @default(autoincrement()) @id
avatarUrl String?
email String @unique
password String
name String
phoneNumber String? @unique
emailSecret String?
phoneSecret String?
bio String?
rooms Room[] @relation(references: [id])
messages Message[]
createdAt DateTime? @default(now())
}
model Room {
id Int @default(autoincrement()) @id
participants User[] @relation(references: [id])
categories Category[] @relation(references: [id])
}
model Category {
id Int @default(autoincrement()) @id
name String? @default("")
rooms Room[] @relation(references: [id])
}
model Message {
id Int @default(autoincrement()) @id
text String? @default("")
sender User @relation(fields: [senderId], references: [id])
senderId Int
}
\ No newline at end of file
type Mutation {
addCategory(name: String): Category!
}
import { prisma } from "../../../utils";
export default {
Mutation: {
addCategory: async (_, args) => {
const { name } = args;
},
},
};
type Mutation {
deleteCategory(id: String!): Boolean!
}
import { prisma } from "../../../utils";
export default {
Mutation: {
deleteCategory: async (_, args) => {
const { id } = args;
},
},
};
type Mutation {
editCategory(id: String!): Category!
}
import { prisma } from "../../../utils";
export default {
Mutation: {
editCategory: async (_, args) => {
const { id } = args;
},
},
};
type Subscription {
sendMessage(message: String!): Message!
}
import { prisma } from "../../../utils";
export default {
Subscription: {
sendMessage: async (_, args) => {
const { message } = args;
},
},
};
type Mutation {
exitRoom(roomId: String!): Boolean!
}
import { prisma } from "../../../utils";
export default {
Mutation: {
exitRoom: async (_, args) => {
const { roomId } = args;
},
},
};
type Query {
seeRoom(id: String!): Room!
}
import { prisma } from "../../../utils";
export default {
Query: {
seeRoom: async (_, args) => {
const { id } = args;
},
},
};
type Query {
TestQL(text: String!): String!
}
export default {
Query: {
TestQL: async (_, args) => {
const { text } = args;
return text;
},
},
};
type Mutation {
createAccount(
name: String!
email: String!
password: String!
bio: String
avatarUrl: String
): AuthPayload!
}
import { prisma, generateToken } from "../../../utils";
import bcrypt from "bcryptjs";
export default {
Mutation: {
createAccount: async (_, args) => {
const { name, password, email, bio = "", avatarUrl = "" } = args;
const encryptPw = await bcrypt.hash(password, 10);
const user = await prisma.user.create({
data: {
name,
email,
bio,
avatarUrl,
password: encryptPw,
},
});
const token = generateToken(user.id);
return { token, user };
},
},
};
type Mutation {
editProfile(
name: String
email: String
bio: String
avatarUrl: String
): User!
}
import { prisma } from "../../../utils";
export default {
Mutation: {
editProfile: async (_, args, { request }) => {},
},
};
type Query {
findEmail(phoneNumber: String!): User!
}
import { prisma, generateSecret } from "../../../utils";
import twilio from "twilio";
export default {
Query: {
findEmail: async (_, args) => {
const { phoneNumber } = args;
const accountSid = process.env.TWILIO_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = new twilio(accountSid, authToken);
const randomWords = generateSecret();
client.messages
.create({
body: `Please enter this word : ${randomWords}`,
to: `${phoneNumber}`,
from: "KhuChat",
})
.then((message) => console.log(message.sid));
const user = await prisma.user.update({
where: {
phoneNumber,
},
data: {
phoneSecret: randomWords,
},
});
return user;
},
},
};
type Mutation {
login(email: String!, password: String!): AuthPayload
}
import { prisma } from "../../../utils";
import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken";
export default {
Mutation: {
login: async (_, args) => {
const { email, password } = args;
const user = await prisma.user.findOne({
where: {
email,
},
});
let vaild;
if (user) {
vaild = await bcrypt.compare(password, user.password);
}
if (!user || !vaild) {
throw new Error("Not vaild email or password");
}
const token = jwt.sign({ id: user.id }, process.env.JWT_SECRET);
return { token, user };
},
},
};
type Mutation {
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 {
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;
}
},
},
};
type Query {
searchUser(name: String!): [User!]!
}
import { prisma } from "../../../utils";
export default {
Query: {
searchUser: async (_, args) => {
const { name } = args;
const user = await prisma.user.findOne({});
},
},
};
type Query {
seeProfile(id: String!): User!
}
import { prisma } from "../../../utils";
export default {
Query: {
seeProfile: async (_, args) => {
const { id } = args;
},
},
};
type User {
id: ID!
avatarUrl: String
name: String
email: String!
password: String
phoneNumber: String
emailSecret: String
phoneSecret: String
bio: String
rooms: [Room]
createdAt: String
messages: [Message]
}
type Room {
id: ID!
participants: [User]
categories: [Category]
}
type Category {
id: ID!
name: String
rooms: [Room]
}
type Message {
id: ID!
text: String
sender: User
}
type AuthPayload {
token: String
user: User
}
import path from "path";
import { makeExecutableSchema } from "graphql-tools";
import { fileLoader, mergeResolvers, mergeTypes } from "merge-graphql-schemas";
const allTypes = fileLoader(path.join(__dirname, "api/**/*.graphql"));
const allResolvers = fileLoader(path.join(__dirname, "api/**/*.js"));
const schema = makeExecutableSchema({
typeDefs: mergeTypes(allTypes),
resolvers: mergeResolvers(allResolvers),
});
export default schema;
import dotenv from "dotenv";
dotenv.config();
import { GraphQLServer } from "graphql-yoga";
import morgan from "morgan";
import schema from "./schema";
import { prisma } from "./utils";
const PORT = process.env.PORT;
const server = new GraphQLServer({
schema,
context: (request) => {
return {
...request,
prisma,
};
},
});
server.express.use(morgan("dev"));
server.start(() => console.log(`server is running : http://localhost:${PORT}`));
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();
export const getUserId = (context) => {
const Authorization = context.request.get("Authorization");
if (Authorization) {
const token = Authorization.replace("Bearer ", "");
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
return userId;
}
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",
];
This diff is collapsed. Click to expand it.
version: "3.7"
services:
mysql:
image: mysql:8.0.19
container_name: mysql
ports:
- 3306:3306
restart: always
environment:
MYSQL_DATABASE: prisma
MYSQL_ROOT_PASSWORD: prisma
volumes:
- /var/lib/mysql
prisma:
links:
- mysql
depends_on:
- mysql
container_name: prisma
ports:
- "5555:5555"
build:
context: ./back/prisma
dockerfile: Dockerfile
environment:
MYSQL_URL: ${MYSQL_URL}
MYSQL_DATABASE: prisma
MYSQL_ROOT_PASSWORD: prisma
volumes:
- /app/prisma
backend:
links:
- mysql
depends_on:
- mysql
container_name: backend
ports:
- "4000:4000"
build:
context: ./back
dockerfile: Dockerfile
environment:
MYSQL_URL: ${MYSQL_URL}
FRONTEND_URL: ${FRONTEND_URL}
volumes:
- ./back:/usr/src/app
- ./back/node_modules:/usr/src/app/node_modules
- ./back/prisma:/usr/src/app/prisma
frontend:
container_name: frontend
ports:
- "3000:3000"
tty: "true"
build:
context: ./front
dockerfile: Dockerfile
command: npm start
environment:
- NODE_ENV=development
- CHOKIDAR_USEPOLLING=true
- BACKEND_URL=${BACKEND_URL}
volumes:
- ./front:/usr/src/app
node_modules
\ No newline at end of file
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
FROM node:12.16.2
RUN mkdir /app
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
\ No newline at end of file
# Capstone design
1st semester capstone design project
Subject : Making website in order to practice web tech
sub-subject : making chat site using JS
\ No newline at end of file
This diff could not be displayed because it is too large.
{
"name": "capstone-front",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"apollo-boost": "^0.4.7",
"core-js": "^3.6.5",
"graphql": "^15.0.0",
"react": "^16.13.1",
"react-apollo-hooks": "^0.5.0",
"react-dom": "^16.13.1",
"react-hooks": "^1.0.1",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
"react-scripts": "3.4.1",
"react-toastify": "^5.5.0",
"styled-components": "^5.1.0",
"styled-reset": "^4.1.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
No preview for this file type
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
import ApolloClient from "apollo-boost";
import { defaults, resolvers } from "./ClientState";
export default new ApolloClient({
uri: "http://localhost:4000",
clientState: {
defaults,
resolvers,
},
});
export const defaults = {};
export const resolvers = {};
import React from "react";
import GlobalStyles from "../Styles/GlobalStyles";
import Header from "./Header";
import Image from "./Image";
import Grid from "./Grid";
export default () => {
return (
<>
<GlobalStyles />
<Header />
<Image />
<Grid />
</>
);
};
import React from "react";
import Styled from "styled-components";
const Article = Styled.div`
width: 70%;
justify-content: center;
align-items: center;
text-align: center;
margin-top: 10px;
border-top: 1px solid black;
`;
export default () => {
return (
<Article>
<h1>Article Title</h1>
</Article>
);
};
import React from "react";
import Styled from "styled-components";
import MenuList from "./MenuList";
import Article from "./Article";
const Grid = Styled.div`
width: 100%;
display: flex;
`;
export default () => {
return (
<Grid>
<MenuList />
<Article />
</Grid>
);
};
import React from "react";
import Styled from "styled-components";
const Header = Styled.div`
width: 100%;
display: flex;
justify-content: center;
margin: 10px 0px;
font-size: 25px;
`;
export default () => {
return (
<Header>
<h1>KHU Chatting service</h1>
</Header>
);
};
import React from "react";
import Styled from "styled-components";
const Image = Styled.div`
width: 100%;
margin: 20px 0px;
display: flex;
justify-content: center;
`;
export default () => {
return (
<Image>
<img src="" alt="sample"></img>
</Image>
);
};
import React from "react";
import Styled from "styled-components";
const MenuBox = Styled.div`
width: 30%;
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
border-top: 1px solid black;
border-right: 1px solid black;
`;
const MenuList = Styled.ol`
`;
const MenuItem = Styled.li`
`;
const Link = Styled.a`
`;
export default () => {
return (
<MenuBox>
<MenuList>
<MenuItem>
<Link href="">1. What is KHU Chat?</Link>
</MenuItem>
</MenuList>
</MenuBox>
);
};
import { createGlobalStyle } from "styled-components";
import reset from "styled-reset";
export default createGlobalStyle`
${reset}
* {
box-sizing: border-box;
}
`;
import React from "react";
import ReactDOM from "react-dom";
import App from "./Components/App";
import { ApolloProvider } from "react-apollo-hooks";
import Client from "./Apollo/Client";
ReactDOM.render(
<ApolloProvider client={Client}>
<App />
</ApolloProvider>,
document.getElementById("root")
);
This diff could not be displayed because it is too large.
{
"name": "capstone",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "docker-compose up",
"build": "docker-compose build",
"stop": "docker-compose down",
"clean": "docker system prune -af",
"clean:volumes": "docker volume prune -f",
"seed": "docker exec -it prisma npm run seed",
"reset:db": "docker-compose rm -fv mysql"
},
"author": {
"name": "sdy, kms",
"email": "vel1024@khu.ac.kr"
},
"license": "ISC"
}