├── .eslintrc.json
├── .gitignore
├── lib
├── database.js
└── passport.js
├── models
└── User.js
├── next.config.js
├── package-lock.json
├── pages
├── _app.js
├── api
│ ├── google
│ │ ├── callback.js
│ │ └── index.js
│ └── hello.js
├── dashboard.js
└── index.js
├── public
├── favicon.ico
└── vercel.svg
└── styles
├── Home.module.css
└── globals.css
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/lib/database.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 |
3 | const connect = () => {
4 | mongoose.connect(
5 | process.env.MONGODB_URI,
6 | { useNewUrlParser: true, useUnifiedTopology: true },
7 | (err) => {
8 | if (err) console.log("Error connecting to MongoDB");
9 | else console.log("Connected to MongoDB");
10 | }
11 | );
12 | };
13 |
14 | export default connect;
15 |
--------------------------------------------------------------------------------
/lib/passport.js:
--------------------------------------------------------------------------------
1 | import passport from "passport";
2 | import { Strategy as GoogleStrategy } from "passport-google-oauth2";
3 | import User from "../models/User";
4 | import jwt from "jsonwebtoken";
5 |
6 | passport.use(
7 | "google",
8 | new GoogleStrategy(
9 | {
10 | clientID: process.env.GOOGLE_CLIENT_ID,
11 | clientSecret: process.env.GOOGLE_CLIENT_SECRET,
12 | callbackURL: "http://localhost:3000/api/google/callback",
13 | },
14 | async (accessToken, refreshToken, profile, done) => {
15 | try {
16 | const obj = await User.findOne({ email: profile.email });
17 | if (!obj) {
18 | // create new user
19 | const newUser = new User({
20 | email: profile.email,
21 | name: profile.displayName,
22 | accessToken,
23 | });
24 | await newUser.save();
25 | const token = await jwt.sign(
26 | {
27 | id: newUser._id,
28 | created: Date.now().toString(),
29 | },
30 | process.env.JWT_SECRET
31 | );
32 | newUser.tokens.push(token);
33 | await newUser.save();
34 | done(null, newUser, { message: "Auth successful", token });
35 | } else {
36 | // login existing user
37 | const token = await jwt.sign(
38 | {
39 | id: obj._id,
40 | created: Date.now().toString(),
41 | },
42 | process.env.JWT_SECRET
43 | );
44 | obj.tokens.push(token);
45 | await obj.save();
46 | done(null, obj, { message: "Auth successful", token });
47 | }
48 | } catch (err) {
49 | console.error(err);
50 | done(err, false, { message: "Internal server error" });
51 | }
52 | }
53 | )
54 | );
55 |
--------------------------------------------------------------------------------
/models/User.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 |
3 | const UserSchema = mongoose.Schema({
4 | name: String,
5 | email: String,
6 | accessToken: String,
7 | tokens: [String],
8 | });
9 |
10 | let User;
11 |
12 | try {
13 | User = mongoose.model("users");
14 | } catch (err) {
15 | User = mongoose.model("users", UserSchema);
16 | }
17 |
18 | export default User;
19 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | reactStrictMode: true,
3 | }
4 |
--------------------------------------------------------------------------------
/pages/_app.js:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css'
2 |
3 | function MyApp({ Component, pageProps }) {
4 | return