Commit 15af72ce authored by Egor Kremnev's avatar Egor Kremnev

add google auth

parent 0f9e029b
This shop api and front clent This shop api and front client
\ No newline at end of file
NODE_FACEBOOK_APP_ID=
NODE_FACEBOOK_SECRET=
NODE_GOOGLE_APP_ID=116339632653-c637pvdqe9csqchit034e3tv77ki94cp.apps.googleusercontent.com
NODE_GOOLGE_SECRET=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
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
# misc # misc
.DS_Store .DS_Store
.env
.env.local .env.local
.env.development.local .env.development.local
.env.test.local .env.test.local
......
...@@ -10,5 +10,13 @@ module.exports = { ...@@ -10,5 +10,13 @@ module.exports = {
db: { db: {
host: 'mongodb://127.0.0.1', host: 'mongodb://127.0.0.1',
database: isTest ? 'shop_test' : 'shop', database: isTest ? 'shop_test' : 'shop',
},
facebook: {
appId: process.env.NODE_FACEBOOK_APP_ID,
secretApp: process.env.NODE_FACEBOOK_SECRET,
},
google: {
appId: process.env.NODE_GOOGLEK_APP_ID,
secretApp: process.env.NODE_GOOGLE_SECRET,
} }
}; };
require('dotenv').config();
const cors = require('cors'); const cors = require('cors');
const express = require('express'); const express = require('express');
const app = express(); const app = express();
......
...@@ -9,6 +9,14 @@ const UserSchema = new Schema({ ...@@ -9,6 +9,14 @@ const UserSchema = new Schema({
type: String, type: String,
required: true required: true
}, },
facebookId: {
type: String,
unique: true
},
googleId: {
type: String,
unique: true
},
username: { username: {
type: String, type: String,
required: true, required: true,
......
...@@ -9,10 +9,13 @@ ...@@ -9,10 +9,13 @@
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"axios": "^1.4.0",
"bcrypt": "^5.1.0", "bcrypt": "^5.1.0",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.18.2", "express": "^4.18.2",
"fix-esm": "^1.0.1", "fix-esm": "^1.0.1",
"google-auth-library": "^9.0.0",
"mongodb": "^5.3.0", "mongodb": "^5.3.0",
"mongoose": "^6.5.0", "mongoose": "^6.5.0",
"mongoose-id-validator": "^0.6.0", "mongoose-id-validator": "^0.6.0",
...@@ -670,6 +673,21 @@ ...@@ -670,6 +673,21 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
}, },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
"integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/balanced-match": { "node_modules/balanced-match": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
...@@ -707,6 +725,14 @@ ...@@ -707,6 +725,14 @@
"node": ">= 10.0.0" "node": ">= 10.0.0"
} }
}, },
"node_modules/bignumber.js": {
"version": "9.1.1",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz",
"integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==",
"engines": {
"node": "*"
}
},
"node_modules/binary-extensions": { "node_modules/binary-extensions": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
...@@ -818,6 +844,11 @@ ...@@ -818,6 +844,11 @@
"ieee754": "^1.1.13" "ieee754": "^1.1.13"
} }
}, },
"node_modules/buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
},
"node_modules/buffer-from": { "node_modules/buffer-from": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
...@@ -950,6 +981,17 @@ ...@@ -950,6 +981,17 @@
"color-support": "bin.js" "color-support": "bin.js"
} }
}, },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/concat-map": { "node_modules/concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
...@@ -1036,6 +1078,14 @@ ...@@ -1036,6 +1078,14 @@
"ms": "2.0.0" "ms": "2.0.0"
} }
}, },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/delegates": { "node_modules/delegates": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
...@@ -1074,6 +1124,25 @@ ...@@ -1074,6 +1124,25 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/dotenv": {
"version": "16.3.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
"integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/motdotla/dotenv?sponsor=1"
}
},
"node_modules/ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
"dependencies": {
"safe-buffer": "^5.0.1"
}
},
"node_modules/ee-first": { "node_modules/ee-first": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
...@@ -1167,6 +1236,11 @@ ...@@ -1167,6 +1236,11 @@
"node": ">= 0.10.0" "node": ">= 0.10.0"
} }
}, },
"node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
},
"node_modules/fill-range": { "node_modules/fill-range": {
"version": "7.0.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
...@@ -1206,6 +1280,38 @@ ...@@ -1206,6 +1280,38 @@
"@babel/plugin-transform-modules-commonjs": "^7.14.5" "@babel/plugin-transform-modules-commonjs": "^7.14.5"
} }
}, },
"node_modules/follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/forwarded": { "node_modules/forwarded": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
...@@ -1292,6 +1398,32 @@ ...@@ -1292,6 +1398,32 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/gaxios": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.0.3.tgz",
"integrity": "sha512-ns+NiTWT9daIerko/qAj8HSPNuNNlzGGrEVB7y8MQ8CP0bymuR8fCql6Ec+rlh7b9BW18JDXQnJNXWMiWO3jlg==",
"dependencies": {
"extend": "^3.0.2",
"https-proxy-agent": "^5.0.0",
"is-stream": "^2.0.0",
"node-fetch": "^2.6.9"
},
"engines": {
"node": ">=14"
}
},
"node_modules/gcp-metadata": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.0.0.tgz",
"integrity": "sha512-Ozxyi23/1Ar51wjUT2RDklK+3HxqDr8TLBNK8rBBFQ7T85iIGnXnVusauj06QyqCXRFZig8LZC+TUddWbndlpQ==",
"dependencies": {
"gaxios": "^6.0.0",
"json-bigint": "^1.0.0"
},
"engines": {
"node": ">=14"
}
},
"node_modules/gensync": { "node_modules/gensync": {
"version": "1.0.0-beta.2", "version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
...@@ -1352,6 +1484,51 @@ ...@@ -1352,6 +1484,51 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/google-auth-library": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.0.0.tgz",
"integrity": "sha512-IQGjgQoVUAfOk6khqTVMLvWx26R+yPw9uLyb1MNyMQpdKiKt0Fd9sp4NWoINjyGHR8S3iw12hMTYK7O8J07c6Q==",
"dependencies": {
"base64-js": "^1.3.0",
"ecdsa-sig-formatter": "^1.0.11",
"gaxios": "^6.0.0",
"gcp-metadata": "^6.0.0",
"gtoken": "^7.0.0",
"jws": "^4.0.0",
"lru-cache": "^6.0.0"
},
"engines": {
"node": ">=14"
}
},
"node_modules/google-auth-library/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/google-auth-library/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/gtoken": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.0.1.tgz",
"integrity": "sha512-KcFVtoP1CVFtQu0aSk3AyAt2og66PFhZAlkUOuWKwzMLoulHXG5W5wE5xAnHb+yl3/wEFoqGW7/cDGMU8igDZQ==",
"dependencies": {
"gaxios": "^6.0.0",
"jws": "^4.0.0"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/has": { "node_modules/has": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
...@@ -1548,6 +1725,17 @@ ...@@ -1548,6 +1725,17 @@
"node": ">=0.12.0" "node": ">=0.12.0"
} }
}, },
"node_modules/is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/isarray": { "node_modules/isarray": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
...@@ -1569,6 +1757,14 @@ ...@@ -1569,6 +1757,14 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/json-bigint": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
"integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
"dependencies": {
"bignumber.js": "^9.0.0"
}
},
"node_modules/json5": { "node_modules/json5": {
"version": "2.2.3", "version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
...@@ -1580,6 +1776,25 @@ ...@@ -1580,6 +1776,25 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/jwa": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
"integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
"dependencies": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"node_modules/jws": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
"dependencies": {
"jwa": "^2.0.0",
"safe-buffer": "^5.0.1"
}
},
"node_modules/kareem": { "node_modules/kareem": {
"version": "2.4.1", "version": "2.4.1",
"resolved": "https://registry.npmjs.org/kareem/-/kareem-2.4.1.tgz", "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.4.1.tgz",
...@@ -2145,6 +2360,11 @@ ...@@ -2145,6 +2360,11 @@
"node": ">= 0.10" "node": ">= 0.10"
} }
}, },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/pstree.remy": { "node_modules/pstree.remy": {
"version": "1.1.8", "version": "1.1.8",
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
......
...@@ -15,10 +15,13 @@ ...@@ -15,10 +15,13 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"axios": "^1.4.0",
"bcrypt": "^5.1.0", "bcrypt": "^5.1.0",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.18.2", "express": "^4.18.2",
"fix-esm": "^1.0.1", "fix-esm": "^1.0.1",
"google-auth-library": "^9.0.0",
"mongodb": "^5.3.0", "mongodb": "^5.3.0",
"mongoose": "^6.5.0", "mongoose": "^6.5.0",
"mongoose-id-validator": "^0.6.0", "mongoose-id-validator": "^0.6.0",
......
const router = require('express').Router(); const router = require('express').Router();
const User = require('../models/User'); const User = require('../models/User');
const auth = require("../middleware/auth"); const auth = require("../middleware/auth");
const config = require('../config');
const axios = require("axios");
const {OAuth2Client} = require("google-auth-library");
const {nanoid} = require('fix-esm').require("nanoid");
router.post('/', async (req, res) => { router.post('/', async (req, res) => {
try { try {
...@@ -78,4 +82,81 @@ router.delete('/logout', auth, async (req, res) => { ...@@ -78,4 +82,81 @@ router.delete('/logout', auth, async (req, res) => {
res.send({message: 'Success'}); res.send({message: 'Success'});
}); });
router.post('/facebookLogin', async (req, res) => {
const inputToken = req.body.accessToken;
const accessToken = config.facebook.appId + '|' + config.facebook.secretApp;
const debugTokenUrl = `https://graph.facebook.com/debug_token?input_token=${inputToken}&access_token=${accessToken}`;
try {
const response = await axios.get(debugTokenUrl).then(res => res.data.data);
if (response.error) {
return res.status(401).send({message: 'Facebook token incorrect'});
}
if (req.body.id !== response.user_id) {
return res.status(401).send({message: 'Wrong user ID'});
}
let user = await User.findOne({facebookId: req.body.id});
if (!user) {
user = new User({
username: req.body.email,
facebookId: req.body.id,
displayName: req.body.name,
password: nanoid(),
});
}
user.generateToken();
await user.save();
return res.send(user);
} catch (e) {
return res.status(400).send({message: 'Facebook token incorrect'});
}
});
router.post('/googleLogin', async (req, res) => {
const idToken = req.body.tokenObj.id_token;
const profileData = req.body.profileObj;
try {
const client = new OAuth2Client();
const ticket = await client.verifyIdToken({
idToken: idToken,
audience: config.google.appId
});
const payload = ticket.getPayload();
if (payload.error) {
return res.status(401).send({message: 'Google token incorrect'});
}
if (profileData.googleId !== payload.sub) {
return res.status(401).send({message: 'Wrong user ID'});
}
let user = await User.findOne({googleId: profileData.googleId});
if (!user) {
user = new User({
username: profileData.email,
googleId: profileData.googleId,
displayName: profileData.name,
password: nanoid(),
});
}
user.generateToken();
await user.save();
return res.send(user);
} catch (e) {
return res.status(400).send({message: 'Google token incorrect'});
}
});
module.exports = router; module.exports = router;
...@@ -8,8 +8,10 @@ ...@@ -8,8 +8,10 @@
"name": "front", "name": "front",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@dump-work/react-google-login": "^6.0.14",
"@emotion/react": "^11.10.6", "@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6", "@emotion/styled": "^11.10.6",
"@greatsumini/react-facebook-login": "^3.3.3",
"@mui/icons-material": "^5.11.16", "@mui/icons-material": "^5.11.16",
"@mui/material": "^5.11.16", "@mui/material": "^5.11.16",
"@mui/styled-engine-sc": "^5.11.11", "@mui/styled-engine-sc": "^5.11.11",
...@@ -2194,6 +2196,20 @@ ...@@ -2194,6 +2196,20 @@
"postcss-selector-parser": "^6.0.10" "postcss-selector-parser": "^6.0.10"
} }
}, },
"node_modules/@dump-work/react-google-login": {
"version": "6.0.14",
"resolved": "https://registry.npmjs.org/@dump-work/react-google-login/-/react-google-login-6.0.14.tgz",
"integrity": "sha512-szoS1jYvhrkBqSudGJFUYS3Qd20CJ9Ye4etN7DTOkM3gxJHCiqZUoQLhzV0DJPBC6y0TkWg56n47eTutX5OaGQ==",
"dependencies": {
"@types/react": "*",
"jwt-decode": "^3.1.2",
"prop-types": "^15.6.0"
},
"peerDependencies": {
"react": "^16 || ^17",
"react-dom": "^16 || ^17"
}
},
"node_modules/@emotion/babel-plugin": { "node_modules/@emotion/babel-plugin": {
"version": "11.10.6", "version": "11.10.6",
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz",
...@@ -2425,6 +2441,14 @@ ...@@ -2425,6 +2441,14 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
} }
}, },
"node_modules/@greatsumini/react-facebook-login": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/@greatsumini/react-facebook-login/-/react-facebook-login-3.3.3.tgz",
"integrity": "sha512-Y5D7EncR3iy/X/OfWwjjpM5OW0XV6PCE08RZUV/yhAE413PEBIlML7S6z69BcpUPWO5XzEt7cytHChUdwXO4Dw==",
"peerDependencies": {
"react": "^16.0.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/@humanwhocodes/config-array": { "node_modules/@humanwhocodes/config-array": {
"version": "0.11.8", "version": "0.11.8",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
...@@ -11714,6 +11738,11 @@ ...@@ -11714,6 +11738,11 @@
"node": ">=4.0" "node": ">=4.0"
} }
}, },
"node_modules/jwt-decode": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
"integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
},
"node_modules/kind-of": { "node_modules/kind-of": {
"version": "6.0.3", "version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
......
...@@ -3,8 +3,10 @@ ...@@ -3,8 +3,10 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@dump-work/react-google-login": "^6.0.14",
"@emotion/react": "^11.10.6", "@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6", "@emotion/styled": "^11.10.6",
"@greatsumini/react-facebook-login": "^3.3.3",
"@mui/icons-material": "^5.11.16", "@mui/icons-material": "^5.11.16",
"@mui/material": "^5.11.16", "@mui/material": "^5.11.16",
"@mui/styled-engine-sc": "^5.11.11", "@mui/styled-engine-sc": "^5.11.11",
...@@ -23,7 +25,7 @@ ...@@ -23,7 +25,7 @@
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "HTTPS=true react-scripts start",
"build": "react-scripts build", "build": "react-scripts build",
"test": "react-scripts test", "test": "react-scripts test",
"eject": "react-scripts eject", "eject": "react-scripts eject",
......
import FacebookLogin from "@greatsumini/react-facebook-login";
import {facebookAppId} from '../../../constants/config';
import {Button} from "@mui/material";
import {facebookLogin} from "../../../store/actions/usersActions";
import {useDispatch} from "react-redux";
import {useNavigate} from "react-router-dom";
const FacebookLoginButton = () => {
const dispatch = useDispatch();
const navigate = useNavigate();
return <FacebookLogin
appId={facebookAppId}
initParams={{
version: 'v17.0',
xfbml: true,
}}
onSuccess={(response) => {
console.log('Login Success!', response);
dispatch(facebookLogin({data: response, callback: () => navigate('/')}));
}}
onFail={(error) => {
console.log('Login Failed!', error);
}}
onProfileSuccess={(response) => {
console.log('Get Profile Success!', response);
}}
render={({onClick, logout}) => (
<Button onClick={onClick}>
Enter with facebook
</Button>
)}
/>
};
export default FacebookLoginButton;
import GoogleLogin from "@dump-work/react-google-login";
import {googleAppId} from '../../../constants/config';
import {Button} from "@mui/material";
import {useDispatch} from "react-redux";
import {useNavigate} from "react-router-dom";
import {googleLogin} from "../../../store/actions/usersActions";
const GoogleLoginButton = () => {
const dispatch = useDispatch();
const navigate = useNavigate();
return <GoogleLogin
clientId={googleAppId}
onFailure={(error) => {
console.log('Login Failed!', error);
}}
onSuccess={(response) => {
console.log('Login Success!', response);
dispatch(googleLogin({data: response, callback: () => navigate('/')}));
}}
render={({ onClick, logout }) => (
<Button onClick={onClick}>
Enter with Google
</Button>
)}
/>;
};
export default GoogleLoginButton;
...@@ -7,3 +7,5 @@ if (process.env.REACT_APP_API_HOST_ENV) { ...@@ -7,3 +7,5 @@ if (process.env.REACT_APP_API_HOST_ENV) {
export const apiUrl = host; export const apiUrl = host;
export const uploadUrl = apiUrl + '/uploads'; export const uploadUrl = apiUrl + '/uploads';
export const facebookAppId = 606018451709501;
export const googleAppId = '116339632653-c637pvdqe9csqchit034e3tv77ki94cp.apps.googleusercontent.com';
...@@ -8,6 +8,8 @@ import {useDispatch, useSelector} from "react-redux"; ...@@ -8,6 +8,8 @@ import {useDispatch, useSelector} from "react-redux";
import {loginUser} from "../../../store/actions/usersActions"; import {loginUser} from "../../../store/actions/usersActions";
import FormElement from "../../../components/UI/Form/FormElement/FormElement"; import FormElement from "../../../components/UI/Form/FormElement/FormElement";
import {setLoginError} from "../../../store/services/usersSlice"; import {setLoginError} from "../../../store/services/usersSlice";
import FacebookLoginButton from "../../../components/SocialAuth/FacebookLoginButton/FacebookLoginButton";
import GoogleLoginButton from "../../../components/SocialAuth/GoogleLoginButton/GoogleLoginButton";
const theme = createTheme(); const theme = createTheme();
...@@ -94,6 +96,14 @@ const Login = () => { ...@@ -94,6 +96,14 @@ const Login = () => {
</Link> </Link>
</Grid> </Grid>
</Grid> </Grid>
<Grid container justifyContent="flex-end">
<Grid item>
<FacebookLoginButton/>
</Grid>
<Grid item>
<GoogleLoginButton/>
</Grid>
</Grid>
</Box> </Box>
</Box> </Box>
</Container> </Container>
......
...@@ -8,6 +8,8 @@ import {useDispatch, useSelector} from "react-redux"; ...@@ -8,6 +8,8 @@ import {useDispatch, useSelector} from "react-redux";
import {registerUser} from "../../../store/actions/usersActions"; import {registerUser} from "../../../store/actions/usersActions";
import FormElement from "../../../components/UI/Form/FormElement/FormElement"; import FormElement from "../../../components/UI/Form/FormElement/FormElement";
import {setRegisterError} from "../../../store/services/usersSlice"; import {setRegisterError} from "../../../store/services/usersSlice";
import FacebookLoginButton from "../../../components/SocialAuth/FacebookLoginButton/FacebookLoginButton";
import GoogleLoginButton from "../../../components/SocialAuth/GoogleLoginButton/GoogleLoginButton";
const theme = createTheme(); const theme = createTheme();
...@@ -99,6 +101,14 @@ const Register = () => { ...@@ -99,6 +101,14 @@ const Register = () => {
</Link> </Link>
</Grid> </Grid>
</Grid> </Grid>
<Grid container justifyContent="flex-end">
<Grid item>
<FacebookLoginButton/>
</Grid>
<Grid item>
<GoogleLoginButton/>
</Grid>
</Grid>
</Box> </Box>
</Box> </Box>
</Container> </Container>
......
...@@ -59,3 +59,33 @@ export const updateUser = createAsyncThunk( ...@@ -59,3 +59,33 @@ export const updateUser = createAsyncThunk(
throw e; throw e;
}) })
); );
export const googleLogin = createAsyncThunk(
'users/googleLogin',
async ({data, callback}, {dispatch}) => await axiosApi
.post('/users/googleLogin', data)
.then(res => {
dispatch(setUser(res.data));
callback();
})
.catch(e => {
if (e?.response?.data) dispatch(setLoginError(e.response.data));
else dispatch(setLoginError(e));
throw e;
})
);
export const facebookLogin = createAsyncThunk(
'users/facebookLogin',
async ({data, callback}, {dispatch}) => await axiosApi
.post('/users/facebookLogin', data)
.then(res => {
dispatch(setUser(res.data));
callback();
})
.catch(e => {
if (e?.response?.data) dispatch(setLoginError(e.response.data));
else dispatch(setLoginError(e));
throw e;
})
);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment