Merge branch 'master' of https://bitbucket.org/vel1024/capstone
Showing
54 changed files
with
450 additions
and
513 deletions
... | @@ -4,6 +4,8 @@ | ... | @@ -4,6 +4,8 @@ |
4 | 4 | ||
5 | Subject : Making website in order to practice latest web technologies | 5 | Subject : Making website in order to practice latest web technologies |
6 | 6 | ||
7 | +- (Tech : react.js, react hooks, styled-components, GraphQL, Prisma, Apollo, AWS, Docker, sendGrid, Twilio, Maxmind) | ||
8 | + | ||
7 | sub-subject : making chat site using JS | 9 | sub-subject : making chat site using JS |
8 | 10 | ||
9 | version | 11 | version |
... | @@ -16,13 +18,12 @@ Atom : 1.45.0 | ... | @@ -16,13 +18,12 @@ Atom : 1.45.0 |
16 | - 4/6 ~ 4/12 | 18 | - 4/6 ~ 4/12 |
17 | - [x] Set development environment | 19 | - [x] Set development environment |
18 | 20 | ||
19 | - (tech : react.js, react hooks, styled-components, GraphQL, Prisma, Apollo, AWS, Docker) | ||
20 | - | ||
21 | - 4/13 ~ 4/19 | 21 | - 4/13 ~ 4/19 |
22 | -- [x] login, sign up (using JWT, sendGrid), Create Docker-compose | 22 | +- [x] login, sign up, Create Docker-compose |
23 | 23 | ||
24 | - 4/20 ~ 4/26 | 24 | - 4/20 ~ 4/26 |
25 | -- [ ] Find ID, PW | 25 | +- [X] Find ID, PW |
26 | + : find password : sendgrid, find userID : twilio | ||
26 | 27 | ||
27 | - 4/27 ~ 5/3 | 28 | - 4/27 ~ 5/3 |
28 | - [ ] Make chat room (using GraphQL's subscription) | 29 | - [ ] Make chat room (using GraphQL's subscription) | ... | ... |
... | @@ -4,6 +4,8 @@ | ... | @@ -4,6 +4,8 @@ |
4 | 4 | ||
5 | Subject : Making website in order to practice latest web technologies | 5 | Subject : Making website in order to practice latest web technologies |
6 | 6 | ||
7 | +- (Tech : react.js, react hooks, styled-components, GraphQL, Prisma, Apollo, AWS, Docker, sendGrid, Twilio, Maxmind) | ||
8 | + | ||
7 | sub-subject : making chat site using JS | 9 | sub-subject : making chat site using JS |
8 | 10 | ||
9 | # Schedule | 11 | # Schedule |
... | @@ -11,20 +13,19 @@ sub-subject : making chat site using JS | ... | @@ -11,20 +13,19 @@ sub-subject : making chat site using JS |
11 | - 4/6 ~ 4/12 | 13 | - 4/6 ~ 4/12 |
12 | - [x] Set development environment | 14 | - [x] Set development environment |
13 | 15 | ||
14 | - (tech : react.js, react hooks, styled-components, GraphQL, Prisma, Apollo, AWS, Docker) | ||
15 | - | ||
16 | - 4/13 ~ 4/19 | 16 | - 4/13 ~ 4/19 |
17 | -- [x] login, sign up (using JWT, sendGrid), Create Docker-compose | 17 | +- [x] login, sign up, Create Docker-compose |
18 | 18 | ||
19 | - 4/20 ~ 4/26 | 19 | - 4/20 ~ 4/26 |
20 | -- [ ] Find ID, PW | 20 | +- [X] Find ID, PW <br> |
21 | + -> find password : sendgrid || find userID : twilio | ||
21 | 22 | ||
22 | - 4/27 ~ 5/3 | 23 | - 4/27 ~ 5/3 |
23 | - [ ] Make chat room (using GraphQL's subscription) | 24 | - [ ] Make chat room (using GraphQL's subscription) |
24 | 25 | ||
25 | - 5/4 ~ 5/10 | 26 | - 5/4 ~ 5/10 |
26 | - [ ] Mid-term exam, Debugging | 27 | - [ ] Mid-term exam, Debugging |
27 | - | 28 | + |
28 | - 5/11 ~ 5/17 | 29 | - 5/11 ~ 5/17 |
29 | - [ ] Plan chat category and make code | 30 | - [ ] Plan chat category and make code |
30 | 31 | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -15,21 +15,23 @@ | ... | @@ -15,21 +15,23 @@ |
15 | "homepage": "https://bitbucket.org/vel1024/capstone2#readme", | 15 | "homepage": "https://bitbucket.org/vel1024/capstone2#readme", |
16 | "dependencies": { | 16 | "dependencies": { |
17 | "@prisma/client": "^2.0.0-beta.2", | 17 | "@prisma/client": "^2.0.0-beta.2", |
18 | + "@sendgrid/mail": "^7.0.1", | ||
18 | "bcryptjs": "^2.4.3", | 19 | "bcryptjs": "^2.4.3", |
20 | + "country-data": "0.0.31", | ||
19 | "dotenv": "^8.2.0", | 21 | "dotenv": "^8.2.0", |
20 | "graphql-tools": "^4.0.7", | 22 | "graphql-tools": "^4.0.7", |
21 | "graphql-yoga": "^1.18.3", | 23 | "graphql-yoga": "^1.18.3", |
22 | "jsonwebtoken": "^8.5.1", | 24 | "jsonwebtoken": "^8.5.1", |
23 | "merge-graphql-schemas": "^1.7.7", | 25 | "merge-graphql-schemas": "^1.7.7", |
24 | - "nodemailer": "^6.4.6", | 26 | + "passport": "^0.4.1", |
25 | - "nodemailer-sendgrid-transport": "^0.2.0", | 27 | + "passport-jwt": "^4.0.0", |
26 | "twilio": "^3.42.2" | 28 | "twilio": "^3.42.2" |
27 | }, | 29 | }, |
28 | "devDependencies": { | 30 | "devDependencies": { |
29 | "@babel/core": "^7.9.0", | 31 | "@babel/core": "^7.9.0", |
30 | "@babel/node": "^7.8.7", | 32 | "@babel/node": "^7.8.7", |
31 | "@babel/preset-env": "^7.9.0", | 33 | "@babel/preset-env": "^7.9.0", |
32 | - "@prisma/cli": "^2.0.0-beta.2", | 34 | + "@prisma/cli": "^2.0.0-beta.3", |
33 | "morgan": "^1.10.0", | 35 | "morgan": "^1.10.0", |
34 | "nodemon": "^2.0.2" | 36 | "nodemon": "^2.0.2" |
35 | } | 37 | } | ... | ... |
1 | -# Migration `20200419160117-init` | ||
2 | - | ||
3 | -This migration has been generated by sdy at 4/19/2020, 4:01:17 PM. | ||
4 | -You can check out the [state of the schema](./schema.prisma) after the migration. | ||
5 | - | ||
6 | -## Database Steps | ||
7 | - | ||
8 | -```sql | ||
9 | -CREATE TABLE `chat_schema`.`User` ( | ||
10 | - `avatarUrl` varchar(191) , | ||
11 | - `bio` varchar(191) , | ||
12 | - `createdAt` datetime DEFAULT CURRENT_TIMESTAMP , | ||
13 | - `email` varchar(191) NOT NULL , | ||
14 | - `id` int NOT NULL AUTO_INCREMENT, | ||
15 | - `loginSecret` varchar(191) , | ||
16 | - `name` varchar(191) NOT NULL , | ||
17 | - `password` varchar(191) NOT NULL , | ||
18 | - PRIMARY KEY (`id`) | ||
19 | -) | ||
20 | -DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci | ||
21 | - | ||
22 | -CREATE TABLE `chat_schema`.`Room` ( | ||
23 | - `id` int NOT NULL AUTO_INCREMENT, | ||
24 | - PRIMARY KEY (`id`) | ||
25 | -) | ||
26 | -DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci | ||
27 | - | ||
28 | -CREATE TABLE `chat_schema`.`Category` ( | ||
29 | - `id` int NOT NULL AUTO_INCREMENT, | ||
30 | - `name` varchar(191) DEFAULT '' , | ||
31 | - PRIMARY KEY (`id`) | ||
32 | -) | ||
33 | -DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci | ||
34 | - | ||
35 | -CREATE TABLE `chat_schema`.`Message` ( | ||
36 | - `id` int NOT NULL AUTO_INCREMENT, | ||
37 | - `senderId` int NOT NULL , | ||
38 | - `text` varchar(191) DEFAULT '' , | ||
39 | - PRIMARY KEY (`id`) | ||
40 | -) | ||
41 | -DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci | ||
42 | - | ||
43 | -CREATE TABLE `chat_schema`.`_RoomToUser` ( | ||
44 | - `A` int NOT NULL , | ||
45 | - `B` int NOT NULL | ||
46 | -) | ||
47 | -DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci | ||
48 | - | ||
49 | -CREATE TABLE `chat_schema`.`_CategoryToRoom` ( | ||
50 | - `A` int NOT NULL , | ||
51 | - `B` int NOT NULL | ||
52 | -) | ||
53 | -DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci | ||
54 | - | ||
55 | -CREATE UNIQUE INDEX `User.email` ON `chat_schema`.`User`(`email`) | ||
56 | - | ||
57 | -CREATE UNIQUE INDEX `_RoomToUser_AB_unique` ON `chat_schema`.`_RoomToUser`(`A`,`B`) | ||
58 | - | ||
59 | -CREATE INDEX `_RoomToUser_B_index` ON `chat_schema`.`_RoomToUser`(`B`) | ||
60 | - | ||
61 | -CREATE UNIQUE INDEX `_CategoryToRoom_AB_unique` ON `chat_schema`.`_CategoryToRoom`(`A`,`B`) | ||
62 | - | ||
63 | -CREATE INDEX `_CategoryToRoom_B_index` ON `chat_schema`.`_CategoryToRoom`(`B`) | ||
64 | - | ||
65 | -ALTER TABLE `chat_schema`.`Message` ADD FOREIGN KEY (`senderId`) REFERENCES `chat_schema`.`User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE | ||
66 | - | ||
67 | -ALTER TABLE `chat_schema`.`_RoomToUser` ADD FOREIGN KEY (`A`) REFERENCES `chat_schema`.`Room`(`id`) ON DELETE CASCADE ON UPDATE CASCADE | ||
68 | - | ||
69 | -ALTER TABLE `chat_schema`.`_RoomToUser` ADD FOREIGN KEY (`B`) REFERENCES `chat_schema`.`User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE | ||
70 | - | ||
71 | -ALTER TABLE `chat_schema`.`_CategoryToRoom` ADD FOREIGN KEY (`A`) REFERENCES `chat_schema`.`Category`(`id`) ON DELETE CASCADE ON UPDATE CASCADE | ||
72 | - | ||
73 | -ALTER TABLE `chat_schema`.`_CategoryToRoom` ADD FOREIGN KEY (`B`) REFERENCES `chat_schema`.`Room`(`id`) ON DELETE CASCADE ON UPDATE CASCADE | ||
74 | - | ||
75 | -DROP TABLE `chat_schema`.`_migration`; | ||
76 | - | ||
77 | -DROP TABLE `chat_schema`.`test`; | ||
78 | -``` | ||
79 | - | ||
80 | -## Changes | ||
81 | - | ||
82 | -```diff | ||
83 | -diff --git schema.prisma schema.prisma | ||
84 | -migration ..20200419160117-init | ||
85 | ---- datamodel.dml | ||
86 | -+++ datamodel.dml | ||
87 | -@@ -1,0 +1,41 @@ | ||
88 | -+generator client { | ||
89 | -+ provider = "prisma-client-js" | ||
90 | -+ binaryTargets = ["native", "debian-openssl-1.1.x"] | ||
91 | -+} | ||
92 | -+ | ||
93 | -+datasource db { | ||
94 | -+ provider = "mysql" | ||
95 | -+ url = env("DATABASE_URL") | ||
96 | -+} | ||
97 | -+ | ||
98 | -+model User { | ||
99 | -+ id Int @default(autoincrement()) @id | ||
100 | -+ avatarUrl String? | ||
101 | -+ email String @unique | ||
102 | -+ password String | ||
103 | -+ name String | ||
104 | -+ loginSecret String? | ||
105 | -+ bio String? | ||
106 | -+ rooms Room[] @relation(references: [id]) | ||
107 | -+ messages Message[] | ||
108 | -+ createdAt DateTime? @default(now()) | ||
109 | -+} | ||
110 | -+ | ||
111 | -+model Room { | ||
112 | -+ id Int @default(autoincrement()) @id | ||
113 | -+ participants User[] @relation(references: [id]) | ||
114 | -+ categories Category[] @relation(references: [id]) | ||
115 | -+} | ||
116 | -+ | ||
117 | -+model Category { | ||
118 | -+ id Int @default(autoincrement()) @id | ||
119 | -+ name String? @default("") | ||
120 | -+ rooms Room[] @relation(references: [id]) | ||
121 | -+} | ||
122 | -+ | ||
123 | -+model Message { | ||
124 | -+ id Int @default(autoincrement()) @id | ||
125 | -+ text String? @default("") | ||
126 | -+ sender User @relation(fields: [senderId], references: [id]) | ||
127 | -+ senderId Int | ||
128 | -+} | ||
129 | -``` | ||
130 | - | ||
131 | - |
1 | -generator client { | ||
2 | - provider = "prisma-client-js" | ||
3 | - binaryTargets = ["native", "debian-openssl-1.1.x"] | ||
4 | -} | ||
5 | - | ||
6 | -datasource db { | ||
7 | - provider = "mysql" | ||
8 | - url = "***" | ||
9 | -} | ||
10 | - | ||
11 | -model User { | ||
12 | - id Int @default(autoincrement()) @id | ||
13 | - avatarUrl String? | ||
14 | - email String @unique | ||
15 | - password String | ||
16 | - name String | ||
17 | - loginSecret String? | ||
18 | - bio String? | ||
19 | - rooms Room[] @relation(references: [id]) | ||
20 | - messages Message[] | ||
21 | - createdAt DateTime? @default(now()) | ||
22 | -} | ||
23 | - | ||
24 | -model Room { | ||
25 | - id Int @default(autoincrement()) @id | ||
26 | - participants User[] @relation(references: [id]) | ||
27 | - categories Category[] @relation(references: [id]) | ||
28 | -} | ||
29 | - | ||
30 | -model Category { | ||
31 | - id Int @default(autoincrement()) @id | ||
32 | - name String? @default("") | ||
33 | - rooms Room[] @relation(references: [id]) | ||
34 | -} | ||
35 | - | ||
36 | -model Message { | ||
37 | - id Int @default(autoincrement()) @id | ||
38 | - text String? @default("") | ||
39 | - sender User @relation(fields: [senderId], references: [id]) | ||
40 | - senderId Int | ||
41 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
This diff is collapsed. Click to expand it.
1 | -# Migration `20200424124259-init` | ||
2 | - | ||
3 | -This migration has been generated by sdy at 4/24/2020, 12:42:59 PM. | ||
4 | -You can check out the [state of the schema](./schema.prisma) after the migration. | ||
5 | - | ||
6 | -## Database Steps | ||
7 | - | ||
8 | -```sql | ||
9 | -CREATE TABLE `chat_schema`.`User` ( | ||
10 | - `avatarUrl` varchar(191) , | ||
11 | - `bio` varchar(191) , | ||
12 | - `createdAt` datetime DEFAULT CURRENT_TIMESTAMP , | ||
13 | - `email` varchar(191) NOT NULL , | ||
14 | - `emailSecret` varchar(191) , | ||
15 | - `id` int NOT NULL AUTO_INCREMENT, | ||
16 | - `name` varchar(191) NOT NULL , | ||
17 | - `password` varchar(191) NOT NULL , | ||
18 | - `phoneNumber` int , | ||
19 | - `phoneSecret` varchar(191) , | ||
20 | - PRIMARY KEY (`id`) | ||
21 | -) | ||
22 | -DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci | ||
23 | - | ||
24 | -CREATE TABLE `chat_schema`.`Room` ( | ||
25 | - `id` int NOT NULL AUTO_INCREMENT, | ||
26 | - PRIMARY KEY (`id`) | ||
27 | -) | ||
28 | -DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci | ||
29 | - | ||
30 | -CREATE TABLE `chat_schema`.`Category` ( | ||
31 | - `id` int NOT NULL AUTO_INCREMENT, | ||
32 | - `name` varchar(191) DEFAULT '' , | ||
33 | - PRIMARY KEY (`id`) | ||
34 | -) | ||
35 | -DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci | ||
36 | - | ||
37 | -CREATE TABLE `chat_schema`.`Message` ( | ||
38 | - `id` int NOT NULL AUTO_INCREMENT, | ||
39 | - `senderId` int NOT NULL , | ||
40 | - `text` varchar(191) DEFAULT '' , | ||
41 | - PRIMARY KEY (`id`) | ||
42 | -) | ||
43 | -DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci | ||
44 | - | ||
45 | -CREATE TABLE `chat_schema`.`_RoomToUser` ( | ||
46 | - `A` int NOT NULL , | ||
47 | - `B` int NOT NULL | ||
48 | -) | ||
49 | -DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci | ||
50 | - | ||
51 | -CREATE TABLE `chat_schema`.`_CategoryToRoom` ( | ||
52 | - `A` int NOT NULL , | ||
53 | - `B` int NOT NULL | ||
54 | -) | ||
55 | -DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci | ||
56 | - | ||
57 | -CREATE UNIQUE INDEX `User.email` ON `chat_schema`.`User`(`email`) | ||
58 | - | ||
59 | -CREATE UNIQUE INDEX `_RoomToUser_AB_unique` ON `chat_schema`.`_RoomToUser`(`A`,`B`) | ||
60 | - | ||
61 | -CREATE INDEX `_RoomToUser_B_index` ON `chat_schema`.`_RoomToUser`(`B`) | ||
62 | - | ||
63 | -CREATE UNIQUE INDEX `_CategoryToRoom_AB_unique` ON `chat_schema`.`_CategoryToRoom`(`A`,`B`) | ||
64 | - | ||
65 | -CREATE INDEX `_CategoryToRoom_B_index` ON `chat_schema`.`_CategoryToRoom`(`B`) | ||
66 | - | ||
67 | -ALTER TABLE `chat_schema`.`Message` ADD FOREIGN KEY (`senderId`) REFERENCES `chat_schema`.`User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE | ||
68 | - | ||
69 | -ALTER TABLE `chat_schema`.`_RoomToUser` ADD FOREIGN KEY (`A`) REFERENCES `chat_schema`.`Room`(`id`) ON DELETE CASCADE ON UPDATE CASCADE | ||
70 | - | ||
71 | -ALTER TABLE `chat_schema`.`_RoomToUser` ADD FOREIGN KEY (`B`) REFERENCES `chat_schema`.`User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE | ||
72 | - | ||
73 | -ALTER TABLE `chat_schema`.`_CategoryToRoom` ADD FOREIGN KEY (`A`) REFERENCES `chat_schema`.`Category`(`id`) ON DELETE CASCADE ON UPDATE CASCADE | ||
74 | - | ||
75 | -ALTER TABLE `chat_schema`.`_CategoryToRoom` ADD FOREIGN KEY (`B`) REFERENCES `chat_schema`.`Room`(`id`) ON DELETE CASCADE ON UPDATE CASCADE | ||
76 | - | ||
77 | -DROP TABLE `chat_schema`.`_categorytoroom`; | ||
78 | - | ||
79 | -DROP TABLE `chat_schema`.`_migration`; | ||
80 | - | ||
81 | -DROP TABLE `chat_schema`.`_roomtouser`; | ||
82 | - | ||
83 | -DROP TABLE `chat_schema`.`category`; | ||
84 | - | ||
85 | -DROP TABLE `chat_schema`.`message`; | ||
86 | - | ||
87 | -DROP TABLE `chat_schema`.`room`; | ||
88 | - | ||
89 | -DROP TABLE `chat_schema`.`test`; | ||
90 | - | ||
91 | -DROP TABLE `chat_schema`.`user`; | ||
92 | -``` | ||
93 | - | ||
94 | -## Changes | ||
95 | - | ||
96 | -```diff | ||
97 | -diff --git schema.prisma schema.prisma | ||
98 | -migration 20200419160117-init..20200424124259-init | ||
99 | ---- datamodel.dml | ||
100 | -+++ datamodel.dml | ||
101 | -@@ -4,18 +4,20 @@ | ||
102 | - } | ||
103 | - datasource db { | ||
104 | - provider = "mysql" | ||
105 | -- url = "***" | ||
106 | -+ url = env("DATABASE_URL") | ||
107 | - } | ||
108 | - model User { | ||
109 | - id Int @default(autoincrement()) @id | ||
110 | - avatarUrl String? | ||
111 | - email String @unique | ||
112 | - password String | ||
113 | - name String | ||
114 | -- loginSecret String? | ||
115 | -+ phoneNumber Int? | ||
116 | -+ emailSecret String? | ||
117 | -+ phoneSecret String? | ||
118 | - bio String? | ||
119 | - rooms Room[] @relation(references: [id]) | ||
120 | - messages Message[] | ||
121 | - createdAt DateTime? @default(now()) | ||
122 | -``` | ||
123 | - | ||
124 | - |
1 | -generator client { | ||
2 | - provider = "prisma-client-js" | ||
3 | - binaryTargets = ["native", "debian-openssl-1.1.x"] | ||
4 | -} | ||
5 | - | ||
6 | -datasource db { | ||
7 | - provider = "mysql" | ||
8 | - url = "***" | ||
9 | -} | ||
10 | - | ||
11 | -model User { | ||
12 | - id Int @default(autoincrement()) @id | ||
13 | - avatarUrl String? | ||
14 | - email String @unique | ||
15 | - password String | ||
16 | - name String | ||
17 | - phoneNumber Int? | ||
18 | - emailSecret String? | ||
19 | - phoneSecret String? | ||
20 | - bio String? | ||
21 | - rooms Room[] @relation(references: [id]) | ||
22 | - messages Message[] | ||
23 | - createdAt DateTime? @default(now()) | ||
24 | -} | ||
25 | - | ||
26 | -model Room { | ||
27 | - id Int @default(autoincrement()) @id | ||
28 | - participants User[] @relation(references: [id]) | ||
29 | - categories Category[] @relation(references: [id]) | ||
30 | -} | ||
31 | - | ||
32 | -model Category { | ||
33 | - id Int @default(autoincrement()) @id | ||
34 | - name String? @default("") | ||
35 | - rooms Room[] @relation(references: [id]) | ||
36 | -} | ||
37 | - | ||
38 | -model Message { | ||
39 | - id Int @default(autoincrement()) @id | ||
40 | - text String? @default("") | ||
41 | - sender User @relation(fields: [senderId], references: [id]) | ||
42 | - senderId Int | ||
43 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -{ | ||
2 | - "version": "0.3.14-fixed", | ||
3 | - "steps": [ | ||
4 | - { | ||
5 | - "tag": "CreateField", | ||
6 | - "model": "User", | ||
7 | - "field": "phoneNumber", | ||
8 | - "type": "Int", | ||
9 | - "arity": "Optional" | ||
10 | - }, | ||
11 | - { | ||
12 | - "tag": "CreateField", | ||
13 | - "model": "User", | ||
14 | - "field": "emailSecret", | ||
15 | - "type": "String", | ||
16 | - "arity": "Optional" | ||
17 | - }, | ||
18 | - { | ||
19 | - "tag": "CreateField", | ||
20 | - "model": "User", | ||
21 | - "field": "phoneSecret", | ||
22 | - "type": "String", | ||
23 | - "arity": "Optional" | ||
24 | - }, | ||
25 | - { | ||
26 | - "tag": "DeleteField", | ||
27 | - "model": "User", | ||
28 | - "field": "loginSecret" | ||
29 | - } | ||
30 | - ] | ||
31 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
back/prisma/migrations/migrate.lock
deleted
100644 → 0
1 | -# IF THERE'S A GIT CONFLICT IN THIS FILE, DON'T SOLVE IT MANUALLY! | ||
2 | -# INSTEAD EXECUTE `prisma migrate fix` | ||
3 | -# Prisma Migrate lockfile v1 | ||
4 | -# Read more about conflict resolution here: TODO | ||
5 | - | ||
6 | -20200419160117-init | ||
7 | -20200424124259-init | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | generator client { | 1 | generator client { |
2 | provider = "prisma-client-js" | 2 | provider = "prisma-client-js" |
3 | - binaryTargets = ["native", "debian-openssl-1.1.x"] | 3 | + binaryTargets = ["native", "debian-openssl-1.1.x", "darwin"] |
4 | } | 4 | } |
5 | 5 | ||
6 | datasource db { | 6 | datasource db { |
... | @@ -9,18 +9,19 @@ datasource db { | ... | @@ -9,18 +9,19 @@ datasource db { |
9 | } | 9 | } |
10 | 10 | ||
11 | model User { | 11 | model User { |
12 | - id Int @default(autoincrement()) @id | 12 | + id Int @default(autoincrement()) @id |
13 | - avatarUrl String? | 13 | + avatarUrl String? @default("") |
14 | - email String @unique | 14 | + email String @unique |
15 | - password String | 15 | + password String |
16 | - name String | 16 | + name String |
17 | - phoneNumber String? @unique | 17 | + phoneNum String @default("") @unique |
18 | - emailSecret String? | 18 | + emailSecret String? @default("") |
19 | - phoneSecret String? | 19 | + phoneSecret String? @default("") |
20 | - bio String? | 20 | + bio String? @default("") |
21 | - rooms Room[] @relation(references: [id]) | 21 | + rooms Room[] @relation(references: [id]) |
22 | - messages Message[] | 22 | + sendMessage Message[] @relation("Sender") |
23 | - createdAt DateTime? @default(now()) | 23 | + receiveMessage Message[] @relation("Receiver") |
24 | + createdAt DateTime? @default(now()) | ||
24 | } | 25 | } |
25 | 26 | ||
26 | model Room { | 27 | model Room { |
... | @@ -36,8 +37,11 @@ model Category { | ... | @@ -36,8 +37,11 @@ model Category { |
36 | } | 37 | } |
37 | 38 | ||
38 | model Message { | 39 | model Message { |
39 | - id Int @default(autoincrement()) @id | 40 | + id Int @default(autoincrement()) @id |
40 | - text String? @default("") | 41 | + text String? @default("") |
41 | - sender User @relation(fields: [senderId], references: [id]) | 42 | + from User[] @relation("Sender", references: [id]) |
42 | - senderId Int | 43 | + to User[] @relation("Receiver", references: [id]) |
44 | + room Room @relation(fields: [roomId], references: [id]) | ||
45 | + roomId Int | ||
46 | + createdAt DateTime? @default(now()) | ||
43 | } | 47 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
back/src/api/Chat/newMessage/newMessage.js
0 → 100644
1 | +import { isAuthenticated, prisma } from "../../../utils"; | ||
2 | +import { ONE_TO_ONE_MESSAGE } from "../../../topics"; | ||
3 | + | ||
4 | +export default { | ||
5 | + Mutation: { | ||
6 | + newMessage: async (_, args, { request, pubsub }) => { | ||
7 | + isAuthenticated(request); | ||
8 | + const { user } = request; | ||
9 | + const { receiverId, message, roomId } = args; | ||
10 | + let room = await prisma.room.findOne({ | ||
11 | + where: { | ||
12 | + id: roomId, | ||
13 | + }, | ||
14 | + }); | ||
15 | + room = await prisma.room.update({ | ||
16 | + where: { | ||
17 | + id: roomId, | ||
18 | + }, | ||
19 | + data: { | ||
20 | + participants: { | ||
21 | + connect: [{ id: user.id }, { id: receiverId }], | ||
22 | + }, | ||
23 | + }, | ||
24 | + }); | ||
25 | + // 방이 없는 경우 | ||
26 | + if (room === undefined || room === null) { | ||
27 | + // 보내는 사람과 받는 사람이 다른 경우 | ||
28 | + if (user.id !== receiverId) { | ||
29 | + room = await prisma.room.create({ | ||
30 | + data: { | ||
31 | + participants: { | ||
32 | + connect: [{ id: receiverId }, { id: user.id }], | ||
33 | + }, | ||
34 | + }, | ||
35 | + }); | ||
36 | + } else { | ||
37 | + // 자기 자신에게 보내는 경우 | ||
38 | + room = await prisma.room.create({ | ||
39 | + data: { | ||
40 | + participants: { | ||
41 | + connect: [{ id: user.id }], | ||
42 | + }, | ||
43 | + }, | ||
44 | + }); | ||
45 | + } | ||
46 | + } | ||
47 | + if (!room) { | ||
48 | + throw new Error("There is no room"); | ||
49 | + } | ||
50 | + const subMessage = await prisma.message.create({ | ||
51 | + data: { | ||
52 | + text: message, | ||
53 | + to: { | ||
54 | + connect: { | ||
55 | + id: receiverId, | ||
56 | + }, | ||
57 | + }, | ||
58 | + from: { | ||
59 | + connect: { | ||
60 | + id: user.id, | ||
61 | + }, | ||
62 | + }, | ||
63 | + room: { | ||
64 | + connect: { | ||
65 | + id: room.id, | ||
66 | + }, | ||
67 | + }, | ||
68 | + }, | ||
69 | + }); | ||
70 | + console.log(subMessage); | ||
71 | + pubsub.publish(ONE_TO_ONE_MESSAGE, subMessage); | ||
72 | + return subMessage; | ||
73 | + }, | ||
74 | + }, | ||
75 | +}; |
1 | -import { prisma } from "../../../utils"; | 1 | +import { ONE_TO_ONE_MESSAGE } from "../../../topics"; |
2 | 2 | ||
3 | export default { | 3 | export default { |
4 | Subscription: { | 4 | Subscription: { |
5 | - sendMessage: async (_, args) => { | 5 | + subMessage: { |
6 | - const { message } = args; | 6 | + subscribe: async (_, __, { pubsub }) => { |
7 | + return pubsub.asyncIterator(ONE_TO_ONE_MESSAGE); | ||
8 | + }, | ||
7 | }, | 9 | }, |
8 | }, | 10 | }, |
9 | }; | 11 | }; | ... | ... |
back/src/api/Room/createRoom/createRoom.js
0 → 100644
1 | +import { prisma } from "../../../utils"; | ||
2 | + | ||
3 | +export default { | ||
4 | + Mutation: { | ||
5 | + createRoom: async (_, args) => { | ||
6 | + const { participantsId, categories } = args; | ||
7 | + let newRoom, participantId; | ||
8 | + if (participantsId !== undefined) { | ||
9 | + newRoom = await prisma.room.create({ | ||
10 | + data: { | ||
11 | + participants: { | ||
12 | + connect: { | ||
13 | + id: (participantId = participantsId.forEach( | ||
14 | + (cur, _, __) => cur | ||
15 | + )), | ||
16 | + }, | ||
17 | + }, | ||
18 | + }, | ||
19 | + }); | ||
20 | + } | ||
21 | + if (categories !== undefined) { | ||
22 | + newRoom = await prisma.room.create({ | ||
23 | + data: { | ||
24 | + categories: { | ||
25 | + connect: { | ||
26 | + id: (category = categories.forEach((cur, _, __) => cur)), | ||
27 | + }, | ||
28 | + }, | ||
29 | + }, | ||
30 | + }); | ||
31 | + } | ||
32 | + return newRoom; | ||
33 | + }, | ||
34 | + }, | ||
35 | +}; |
1 | -import { prisma, generateToken } from "../../../utils"; | 1 | +import { prisma, generateToken, changePhoneNumber } from "../../../utils"; |
2 | import bcrypt from "bcryptjs"; | 2 | import bcrypt from "bcryptjs"; |
3 | 3 | ||
4 | export default { | 4 | export default { |
5 | Mutation: { | 5 | Mutation: { |
6 | createAccount: async (_, args) => { | 6 | createAccount: async (_, args) => { |
7 | - const { name, password, email, bio = "", avatarUrl = "" } = args; | 7 | + const { name, password, email, bio, avatarUrl, phoneNum } = args; |
8 | const encryptPw = await bcrypt.hash(password, 10); | 8 | const encryptPw = await bcrypt.hash(password, 10); |
9 | + // TODO: Find user's country code and change new phone number value | ||
10 | + const newPhoneNumber = await changePhoneNumber(phoneNum, "+82"); | ||
9 | const user = await prisma.user.create({ | 11 | const user = await prisma.user.create({ |
10 | data: { | 12 | data: { |
11 | name, | 13 | name, |
... | @@ -13,6 +15,7 @@ export default { | ... | @@ -13,6 +15,7 @@ export default { |
13 | bio, | 15 | bio, |
14 | avatarUrl, | 16 | avatarUrl, |
15 | password: encryptPw, | 17 | password: encryptPw, |
18 | + phoneNum: newPhoneNumber, | ||
16 | }, | 19 | }, |
17 | }); | 20 | }); |
18 | const token = generateToken(user.id); | 21 | const token = generateToken(user.id); | ... | ... |
back/src/api/User/deleteUser/deleteUser.js
0 → 100644
1 | +import { isAuthenticated, prisma } from "../../../utils"; | ||
2 | + | ||
3 | +export default { | ||
4 | + Mutation: { | ||
5 | + deleteUser: async (_, args, { request }) => { | ||
6 | + isAuthenticated(request); | ||
7 | + const { email } = args; | ||
8 | + return prisma.user.delete({ | ||
9 | + where: { | ||
10 | + email, | ||
11 | + }, | ||
12 | + }); | ||
13 | + }, | ||
14 | + }, | ||
15 | +}; |
1 | -import { prisma } from "../../../utils"; | 1 | +import { isAuthenticated, prisma } from "../../../utils"; |
2 | 2 | ||
3 | export default { | 3 | export default { |
4 | Mutation: { | 4 | Mutation: { |
5 | - editProfile: async (_, args, { request }) => {}, | 5 | + editProfile: async (_, args, { request }) => { |
6 | + isAuthenticated(request); | ||
7 | + const { name, email, avatarUrl, bio, phoneNum } = args; | ||
8 | + const user = await prisma.user.findOne({ | ||
9 | + where: { | ||
10 | + email, | ||
11 | + }, | ||
12 | + }); | ||
13 | + if (user) { | ||
14 | + const updateUser = await prisma.user.update({ | ||
15 | + where: { | ||
16 | + email, | ||
17 | + }, | ||
18 | + data: { | ||
19 | + name, | ||
20 | + bio, | ||
21 | + avatarUrl, | ||
22 | + phoneNum, | ||
23 | + }, | ||
24 | + }); | ||
25 | + return updateUser; | ||
26 | + } else { | ||
27 | + throw new Error("There is no such a user"); | ||
28 | + } | ||
29 | + }, | ||
6 | }, | 30 | }, |
7 | }; | 31 | }; | ... | ... |
1 | -import { prisma, generateSecret } from "../../../utils"; | 1 | +import { prisma, isAuthenticated, changePhoneNumber } from "../../../utils"; |
2 | import twilio from "twilio"; | 2 | import twilio from "twilio"; |
3 | 3 | ||
4 | export default { | 4 | export default { |
5 | Query: { | 5 | Query: { |
6 | findEmail: async (_, args) => { | 6 | findEmail: async (_, args) => { |
7 | - const { phoneNumber } = args; | 7 | + const { phoneNum } = args; |
8 | - const accountSid = process.env.TWILIO_SID; | 8 | + const changeNum = await changePhoneNumber(phoneNum, "+82"); |
9 | - const authToken = process.env.TWILIO_AUTH_TOKEN; | 9 | + const user = await prisma.user.findOne({ |
10 | - const client = new twilio(accountSid, authToken); | ||
11 | - const randomWords = generateSecret(); | ||
12 | - client.messages | ||
13 | - .create({ | ||
14 | - body: `Please enter this word : ${randomWords}`, | ||
15 | - to: `${phoneNumber}`, | ||
16 | - from: "KhuChat", | ||
17 | - }) | ||
18 | - .then((message) => console.log(message.sid)); | ||
19 | - | ||
20 | - const user = await prisma.user.update({ | ||
21 | where: { | 10 | where: { |
22 | - phoneNumber, | 11 | + phoneNum: changeNum, |
23 | - }, | ||
24 | - data: { | ||
25 | - phoneSecret: randomWords, | ||
26 | }, | 12 | }, |
27 | }); | 13 | }); |
28 | - return user; | 14 | + if (user && isAuthenticated) { |
15 | + const accountSid = process.env.TWILIO_SID; | ||
16 | + const authToken = process.env.TWILIO_AUTH_TOKEN; | ||
17 | + const twilioPhone = process.env.TWILIO_PHONE_NUMBER; | ||
18 | + const client = new twilio(accountSid, authToken); | ||
19 | + client.messages | ||
20 | + .create({ | ||
21 | + body: `Your Email is : ${user.email}`, | ||
22 | + to: `${changeNum}`, | ||
23 | + from: `${twilioPhone}`, | ||
24 | + }) | ||
25 | + .then((message) => { | ||
26 | + console.log(message.sid); | ||
27 | + }); | ||
28 | + return true; | ||
29 | + } else { | ||
30 | + throw new Error("You need to login first"); | ||
31 | + } | ||
29 | }, | 32 | }, |
30 | }, | 33 | }, |
31 | }; | 34 | }; | ... | ... |
1 | -import { prisma, generateSecret, sendSecretMail } from "../../../utils"; | 1 | +import { prisma, generateSecret, sendEmail } from "../../../utils"; |
2 | import bcrypt from "bcryptjs"; | 2 | import bcrypt from "bcryptjs"; |
3 | 3 | ||
4 | export default { | 4 | export default { |
... | @@ -6,15 +6,14 @@ export default { | ... | @@ -6,15 +6,14 @@ export default { |
6 | requestEmailSecret: async (_, args) => { | 6 | requestEmailSecret: async (_, args) => { |
7 | const { email } = args; | 7 | const { email } = args; |
8 | const emailSecret = generateSecret(); | 8 | const emailSecret = generateSecret(); |
9 | - const encryptSecret = await bcrypt.hash(emailSecret, 10); | ||
10 | try { | 9 | try { |
11 | - await sendSecretMail(email, emailSecret); | 10 | + await sendEmail(email, emailSecret); |
12 | await prisma.user.update({ | 11 | await prisma.user.update({ |
13 | where: { | 12 | where: { |
14 | email, | 13 | email, |
15 | }, | 14 | }, |
16 | data: { | 15 | data: { |
17 | - emailSecret: encryptSecret, | 16 | + emailSecret, |
18 | }, | 17 | }, |
19 | }); | 18 | }); |
20 | return true; | 19 | return true; | ... | ... |
1 | -import { prisma } from "../../../utils"; | 1 | +import { prisma, isAuthenticated } from "../../../utils"; |
2 | import bcrypt from "bcryptjs"; | 2 | import bcrypt from "bcryptjs"; |
3 | 3 | ||
4 | export default { | 4 | export default { |
5 | Mutation: { | 5 | Mutation: { |
6 | - resetPassword: async (_, args) => { | 6 | + resetPassword: async (_, args, { request }) => { |
7 | - const { secret, email, passwordOne, passwordTwo } = args; | 7 | + isAuthenticated(request); |
8 | + const { emailSecret, email, passwordOne, passwordTwo } = args; | ||
8 | const user = await prisma.user.findOne({ | 9 | const user = await prisma.user.findOne({ |
9 | where: { | 10 | where: { |
10 | email, | 11 | email, |
11 | }, | 12 | }, |
12 | }); | 13 | }); |
13 | - const encryptSecret = await bcrypt.hash(user.emailSecret, 10); | 14 | + if (user.emailSecret !== emailSecret) { |
14 | - if (encryptSecret !== secret) { | ||
15 | throw new Error( | 15 | throw new Error( |
16 | "not vaild secret value!, input another value or resend email" | 16 | "not vaild secret value!, input another value or resend email" |
17 | ); | 17 | ); |
... | @@ -20,13 +20,14 @@ export default { | ... | @@ -20,13 +20,14 @@ export default { |
20 | // For check new password is right, the two things must be same. | 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"); | 21 | throw new Error("the two password don't match each other, try again"); |
22 | } else { | 22 | } else { |
23 | + const encyptPW = await bcrypt.hash(passwordOne, 10); | ||
23 | await prisma.user.update({ | 24 | await prisma.user.update({ |
24 | where: { | 25 | where: { |
25 | email, | 26 | email, |
26 | }, | 27 | }, |
27 | data: { | 28 | data: { |
28 | emailSecret: "", | 29 | emailSecret: "", |
29 | - password: passwordOne, | 30 | + password: encyptPW, |
30 | }, | 31 | }, |
31 | }); | 32 | }); |
32 | } | 33 | } | ... | ... |
... | @@ -3,8 +3,24 @@ import { prisma } from "../../../utils"; | ... | @@ -3,8 +3,24 @@ import { prisma } from "../../../utils"; |
3 | export default { | 3 | export default { |
4 | Query: { | 4 | Query: { |
5 | searchUser: async (_, args) => { | 5 | searchUser: async (_, args) => { |
6 | - const { name } = args; | 6 | + const { term } = args; |
7 | - const user = await prisma.user.findOne({}); | 7 | + try { |
8 | + return prisma.user.findMany({ | ||
9 | + where: { | ||
10 | + OR: [ | ||
11 | + { | ||
12 | + name: { contains: term }, | ||
13 | + }, | ||
14 | + { | ||
15 | + email: { contains: term }, | ||
16 | + }, | ||
17 | + ], | ||
18 | + }, | ||
19 | + }); | ||
20 | + } catch (error) { | ||
21 | + console.log(error); | ||
22 | + return null; | ||
23 | + } | ||
8 | }, | 24 | }, |
9 | }, | 25 | }, |
10 | }; | 26 | }; | ... | ... |
1 | -import { prisma } from "../../../utils"; | 1 | +import { prisma, isAuthenticated } from "../../../utils"; |
2 | 2 | ||
3 | export default { | 3 | export default { |
4 | Query: { | 4 | Query: { |
5 | - seeProfile: async (_, args) => { | 5 | + seeProfile: async (_, args, { request }) => { |
6 | - const { id } = args; | 6 | + isAuthenticated(request); |
7 | + const { email } = args; | ||
8 | + return prisma.user.findOne({ | ||
9 | + where: { | ||
10 | + email, | ||
11 | + }, | ||
12 | + }); | ||
7 | }, | 13 | }, |
8 | }, | 14 | }, |
9 | }; | 15 | }; | ... | ... |
1 | type User { | 1 | type User { |
2 | id: ID! | 2 | id: ID! |
3 | avatarUrl: String | 3 | avatarUrl: String |
4 | - name: String | 4 | + name: String! |
5 | email: String! | 5 | email: String! |
6 | - password: String | 6 | + password: String! |
7 | - phoneNumber: String | ||
8 | emailSecret: String | 7 | emailSecret: String |
8 | + phoneNum: String! | ||
9 | phoneSecret: String | 9 | phoneSecret: String |
10 | bio: String | 10 | bio: String |
11 | rooms: [Room] | 11 | rooms: [Room] |
12 | createdAt: String | 12 | createdAt: String |
13 | messages: [Message] | 13 | messages: [Message] |
14 | + from: Message | ||
15 | + to: [Message] | ||
14 | } | 16 | } |
15 | 17 | ||
16 | type Room { | 18 | type Room { |
... | @@ -27,8 +29,12 @@ type Category { | ... | @@ -27,8 +29,12 @@ type Category { |
27 | 29 | ||
28 | type Message { | 30 | type Message { |
29 | id: ID! | 31 | id: ID! |
30 | - text: String | 32 | + text: String! |
31 | - sender: User | 33 | + from: User |
34 | + to: [User] | ||
35 | + room: Room! | ||
36 | + createdAt: String | ||
37 | + updatedAt: String | ||
32 | } | 38 | } |
33 | 39 | ||
34 | type AuthPayload { | 40 | type AuthPayload { | ... | ... |
back/src/passport.js
0 → 100644
1 | +import passport from "passport"; | ||
2 | +import { Strategy, ExtractJwt } from "passport-jwt"; | ||
3 | +import { prisma } from "./utils"; | ||
4 | + | ||
5 | +const JWTOptions = { | ||
6 | + jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), | ||
7 | + secretOrKey: process.env.JWT_SECRET, | ||
8 | +}; | ||
9 | + | ||
10 | +const verifyUser = async (payload, done) => { | ||
11 | + try { | ||
12 | + const user = await prisma.user.findOne({ | ||
13 | + where: { | ||
14 | + id: payload.id, | ||
15 | + }, | ||
16 | + }); | ||
17 | + if (user !== null) { | ||
18 | + return done(null, user); | ||
19 | + } else { | ||
20 | + return done(null, false); | ||
21 | + } | ||
22 | + } catch (error) { | ||
23 | + return done(null, false); | ||
24 | + } | ||
25 | +}; | ||
26 | + | ||
27 | +export const authenticateJWT = (req, res, next) => { | ||
28 | + passport.authenticate("jwt", { session: false }, (error, user) => { | ||
29 | + if (user) { | ||
30 | + req.user = user; | ||
31 | + } | ||
32 | + next(); | ||
33 | + })(req, res, next); | ||
34 | +}; | ||
35 | + | ||
36 | +passport.use(new Strategy(JWTOptions, verifyUser)); | ||
37 | +passport.initialize(); |
1 | import dotenv from "dotenv"; | 1 | import dotenv from "dotenv"; |
2 | dotenv.config(); | 2 | dotenv.config(); |
3 | -import { GraphQLServer } from "graphql-yoga"; | 3 | +import { GraphQLServer, PubSub } from "graphql-yoga"; |
4 | import morgan from "morgan"; | 4 | import morgan from "morgan"; |
5 | import schema from "./schema"; | 5 | import schema from "./schema"; |
6 | -import { prisma } from "./utils"; | 6 | +import "./passport"; |
7 | +import { authenticateJWT } from "./passport"; | ||
7 | 8 | ||
8 | const PORT = process.env.PORT; | 9 | const PORT = process.env.PORT; |
9 | 10 | ||
11 | +const pubsub = new PubSub(); | ||
12 | + | ||
10 | const server = new GraphQLServer({ | 13 | const server = new GraphQLServer({ |
11 | schema, | 14 | schema, |
12 | - context: (request) => { | 15 | + context: ({ request }) => ({ request, pubsub }), |
13 | - return { | ||
14 | - ...request, | ||
15 | - prisma, | ||
16 | - }; | ||
17 | - }, | ||
18 | }); | 16 | }); |
19 | 17 | ||
20 | server.express.use(morgan("dev")); | 18 | server.express.use(morgan("dev")); |
19 | +server.express.use(authenticateJWT); | ||
21 | 20 | ||
22 | server.start(() => console.log(`server is running : http://localhost:${PORT}`)); | 21 | server.start(() => console.log(`server is running : http://localhost:${PORT}`)); | ... | ... |
back/src/topics.js
0 → 100644
1 | +export const ONE_TO_ONE_MESSAGE = "one-to-one message"; |
1 | +import dotenv from "dotenv"; | ||
2 | +dotenv.config(); | ||
1 | import { PrismaClient } from "@prisma/client"; | 3 | import { PrismaClient } from "@prisma/client"; |
2 | import { nouns, adjectives } from "./words"; | 4 | import { nouns, adjectives } from "./words"; |
3 | import jwt from "jsonwebtoken"; | 5 | import jwt from "jsonwebtoken"; |
4 | -import nodemailer from "nodemailer"; | 6 | +import sgMail from "@sendgrid/mail"; |
5 | -import sgTransport from "nodemailer-sendgrid-transport"; | 7 | +sgMail.setApiKey(process.env.SENDGRID_API_KEY); |
6 | 8 | ||
7 | export const prisma = new PrismaClient(); | 9 | export const prisma = new PrismaClient(); |
8 | 10 | ||
... | @@ -16,30 +18,45 @@ export const getUserId = (context) => { | ... | @@ -16,30 +18,45 @@ export const getUserId = (context) => { |
16 | throw new Error("There is no vaild user"); | 18 | throw new Error("There is no vaild user"); |
17 | }; | 19 | }; |
18 | 20 | ||
21 | +export const isAuthenticated = (request) => { | ||
22 | + if (!request.user) { | ||
23 | + throw new Error("You need to login First"); | ||
24 | + } | ||
25 | + return; | ||
26 | +}; | ||
27 | + | ||
28 | +export const changePhoneNumber = (phoneNum, locationNum) => { | ||
29 | + var leftStr = locationNum; | ||
30 | + var rightStr = phoneNum.slice(1, phoneNum.length); | ||
31 | + var newStr = leftStr + rightStr; | ||
32 | + return newStr; | ||
33 | +}; | ||
34 | + | ||
19 | export const generateSecret = () => { | 35 | export const generateSecret = () => { |
20 | const randomNumber = Math.floor(Math.random() * adjectives.length); | 36 | const randomNumber = Math.floor(Math.random() * adjectives.length); |
21 | return `${adjectives[randomNumber]} ${nouns[randomNumber]}`; | 37 | return `${adjectives[randomNumber]} ${nouns[randomNumber]}`; |
22 | }; | 38 | }; |
23 | 39 | ||
24 | -const sendEmail = (email) => { | 40 | +export const generateToken = (id) => jwt.sign({ id }, process.env.JWT_SECRET); |
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 | 41 | ||
35 | -export const sendSecretMail = (address, emailSecret, value) => { | 42 | +export const createEMessage = (userEmail, emailSecret) => { |
36 | - const email = { | 43 | + const emailMessage = { |
37 | - from: "vel1024@khu.ac.kr", | 44 | + to: `${userEmail}`, |
38 | - to: address, | 45 | + from: "KhuChat@KhuChat.com", |
39 | - subject: `Authentication key for forgotten ${value}`, | 46 | + subject: "Email from KhuChat", |
40 | - html: `Hello, This is khuchat, authentication key is <b>${emailSecret}</b>, copy and paste it, Thanks.`, | 47 | + html: `We send email for reset your password, enter this key : <b>${emailSecret}</b>`, |
41 | }; | 48 | }; |
42 | - return sendEmail(email); | 49 | + return emailMessage; |
43 | }; | 50 | }; |
44 | 51 | ||
45 | -export const generateToken = (id) => jwt.sign({ id }, process.env.JWT_SECRET); | 52 | +export const sendEmail = (userEmail, emailSecret) => { |
53 | + sgMail.send(createEMessage(userEmail, emailSecret)).then( | ||
54 | + () => {}, | ||
55 | + (error) => { | ||
56 | + console.error(error); | ||
57 | + if (error.response) { | ||
58 | + console.error(error.response.body); | ||
59 | + } | ||
60 | + } | ||
61 | + ); | ||
62 | +}; | ... | ... |
... | @@ -1174,6 +1174,35 @@ | ... | @@ -1174,6 +1174,35 @@ |
1174 | "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", | 1174 | "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", |
1175 | "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" | 1175 | "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" |
1176 | }, | 1176 | }, |
1177 | + "@fortawesome/fontawesome-common-types": { | ||
1178 | + "version": "0.2.28", | ||
1179 | + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.28.tgz", | ||
1180 | + "integrity": "sha512-gtis2/5yLdfI6n0ia0jH7NJs5i/Z/8M/ZbQL6jXQhCthEOe5Cr5NcQPhgTvFxNOtURE03/ZqUcEskdn2M+QaBg==" | ||
1181 | + }, | ||
1182 | + "@fortawesome/fontawesome-svg-core": { | ||
1183 | + "version": "1.2.28", | ||
1184 | + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.28.tgz", | ||
1185 | + "integrity": "sha512-4LeaNHWvrneoU0i8b5RTOJHKx7E+y7jYejplR7uSVB34+mp3Veg7cbKk7NBCLiI4TyoWS1wh9ZdoyLJR8wSAdg==", | ||
1186 | + "requires": { | ||
1187 | + "@fortawesome/fontawesome-common-types": "^0.2.28" | ||
1188 | + } | ||
1189 | + }, | ||
1190 | + "@fortawesome/free-solid-svg-icons": { | ||
1191 | + "version": "5.13.0", | ||
1192 | + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.13.0.tgz", | ||
1193 | + "integrity": "sha512-IHUgDJdomv6YtG4p3zl1B5wWf9ffinHIvebqQOmV3U+3SLw4fC+LUCCgwfETkbTtjy5/Qws2VoVf6z/ETQpFpg==", | ||
1194 | + "requires": { | ||
1195 | + "@fortawesome/fontawesome-common-types": "^0.2.28" | ||
1196 | + } | ||
1197 | + }, | ||
1198 | + "@fortawesome/react-fontawesome": { | ||
1199 | + "version": "0.1.9", | ||
1200 | + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.9.tgz", | ||
1201 | + "integrity": "sha512-49V3WNysLZU5fZ3sqSuys4nGRytsrxJktbv3vuaXkEoxv22C6T7TEG0TW6+nqVjMnkfCQd5xOnmJoZHMF78tOw==", | ||
1202 | + "requires": { | ||
1203 | + "prop-types": "^15.7.2" | ||
1204 | + } | ||
1205 | + }, | ||
1177 | "@hapi/address": { | 1206 | "@hapi/address": { |
1178 | "version": "2.1.4", | 1207 | "version": "2.1.4", |
1179 | "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", | 1208 | "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", | ... | ... |
... | @@ -3,6 +3,9 @@ | ... | @@ -3,6 +3,9 @@ |
3 | "version": "0.1.0", | 3 | "version": "0.1.0", |
4 | "private": true, | 4 | "private": true, |
5 | "dependencies": { | 5 | "dependencies": { |
6 | + "@fortawesome/fontawesome-svg-core": "^1.2.28", | ||
7 | + "@fortawesome/free-solid-svg-icons": "^5.13.0", | ||
8 | + "@fortawesome/react-fontawesome": "^0.1.9", | ||
6 | "@testing-library/jest-dom": "^4.2.4", | 9 | "@testing-library/jest-dom": "^4.2.4", |
7 | "@testing-library/react": "^9.3.2", | 10 | "@testing-library/react": "^9.3.2", |
8 | "@testing-library/user-event": "^7.1.2", | 11 | "@testing-library/user-event": "^7.1.2", | ... | ... |
front/public/image/coding.jpg
0 → 100644
672 KB
front/public/image/login.jpg
0 → 100644
1.6 MB
front/public/image/main2.jpg
0 → 100644
9.03 MB
front/public/image/question.jpg
0 → 100644
807 KB
front/public/image/signin.jpg
0 → 100644
861 KB
3.14 MB
front/public/image/welcome.jpg
0 → 100644
2.55 MB
... | @@ -7,6 +7,9 @@ const Header = Styled.div` | ... | @@ -7,6 +7,9 @@ const Header = Styled.div` |
7 | justify-content: center; | 7 | justify-content: center; |
8 | margin: 10px 0px; | 8 | margin: 10px 0px; |
9 | font-size: 25px; | 9 | font-size: 25px; |
10 | + font-family: 'Source Code Pro'; | ||
11 | + font-weight: 200; | ||
12 | + font-size: 40px; | ||
10 | `; | 13 | `; |
11 | 14 | ||
12 | export default () => { | 15 | export default () => { | ... | ... |
1 | import React from "react"; | 1 | import React from "react"; |
2 | import Styled from "styled-components"; | 2 | import Styled from "styled-components"; |
3 | +//import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||
4 | +//import { faList, faAddressBook } from "@fortawesome/free-solid-svg-icons"; | ||
5 | +import PropTypes from "prop-types"; | ||
3 | 6 | ||
4 | -const MenuBox = Styled.div` | 7 | +const Container = Styled.div` |
5 | - width: 30%; | 8 | + width: 400px; |
6 | - display: flex; | 9 | + height: 100%; |
7 | - justify-content: center; | ||
8 | - align-items: center; | ||
9 | - margin-top: 10px; | ||
10 | - border-top: 1px solid black; | ||
11 | - border-right: 1px solid black; | ||
12 | `; | 10 | `; |
13 | 11 | ||
14 | -const MenuList = Styled.ol` | 12 | +const Switch = ({ checked = false, isChecked, onClick }) => ( |
15 | -`; | 13 | + <Container checked={checked} onClick={onClick} isChecked={isChecked} /> |
16 | - | 14 | +); |
17 | -const MenuItem = Styled.li` | ||
18 | -`; | ||
19 | 15 | ||
20 | -const Link = Styled.a` | 16 | +Switch.propTypes = { |
21 | -`; | 17 | + checked: PropTypes.bool, |
18 | + isChecked: PropTypes.func, | ||
19 | + onClick: PropTypes.func, | ||
20 | +}; | ||
22 | 21 | ||
23 | export default () => { | 22 | export default () => { |
24 | - return ( | 23 | + return <Switch />; |
25 | - <MenuBox> | ||
26 | - <MenuList> | ||
27 | - <MenuItem> | ||
28 | - <Link href="">1. What is KHU Chat?</Link> | ||
29 | - </MenuItem> | ||
30 | - </MenuList> | ||
31 | - </MenuBox> | ||
32 | - ); | ||
33 | }; | 24 | }; | ... | ... |
front/src/Hooks/useSwitch.js
0 → 100644
... | @@ -2,6 +2,10 @@ import { createGlobalStyle } from "styled-components"; | ... | @@ -2,6 +2,10 @@ import { createGlobalStyle } from "styled-components"; |
2 | import reset from "styled-reset"; | 2 | import reset from "styled-reset"; |
3 | 3 | ||
4 | export default createGlobalStyle` | 4 | export default createGlobalStyle` |
5 | + @import url('https://fonts.googleapis.com/css2?family=Nanum+Brush+Script&display=swap'); | ||
6 | + @import url('https://fonts.googleapis.com/css2?family=Do+Hyeon&family=Nanum+Gothic+Coding:wght@400;700&family=Nanum+Pen+Script&family=Sunflower:wght@300;500;700&display=swap'); | ||
7 | + @import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;0,900;1,200;1,300;1,400;1,500;1,600;1,700;1,900&display=swap'); | ||
8 | + | ||
5 | ${reset} | 9 | ${reset} |
6 | * { | 10 | * { |
7 | box-sizing: border-box; | 11 | box-sizing: border-box; | ... | ... |
package-lock.json
0 → 100644
1 | +{ | ||
2 | + "name": "capstone", | ||
3 | + "version": "1.0.0", | ||
4 | + "lockfileVersion": 1, | ||
5 | + "requires": true, | ||
6 | + "dependencies": { | ||
7 | + "@prisma/cli": { | ||
8 | + "version": "2.0.0-beta.3", | ||
9 | + "resolved": "https://registry.npmjs.org/@prisma/cli/-/cli-2.0.0-beta.3.tgz", | ||
10 | + "integrity": "sha512-VZxeTLLMenhkAyaY4tvTqChcW6QtUkiVvZj7N6A2vi6HsM1Tnf0fIZsiH1h3e/LEnaaDGIUC8F4Gkh2SeyeyCg==", | ||
11 | + "dev": true | ||
12 | + } | ||
13 | + } | ||
14 | +} |
-
Please register or login to post a comment