Skip to content

(WIP)61 Implements google calendar integration backend #88

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: development
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion app.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,55 @@
require('./config/mongoose')
const express = require('express')
const cors = require('cors')
const logger = require('morgan')
const cookieParser = require('cookie-parser')
const createError = require('http-errors')
const path = require('path')

const passport = require('passport')

const indexRouter = require('./app/routes/index')
const authRouter = require('./app/routes/auth')
const usersRouter = require('./app/routes/user')
const postRouter = require('./app/routes/post')
const shortUrlRouter = require('./app/routes/urlShortner')
const oauthRouter = require('./app/routes/oauth')
const calendarRoute = require('./app/routes/calendar')

const app = express()

// view engine setup
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'ejs')

app.use(cors())
app.use(logger('tiny'))
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(express.static(path.join(__dirname, 'public')))

app.use(
require('express-session')({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true
})
)
app.use(passport.initialize())
app.use(passport.session())

app.use('/', indexRouter)
app.use('/auth', authRouter)
app.use('/user', usersRouter)
app.use('/post', postRouter)
app.use('/shortUrl', shortUrlRouter)
app.use('/oauth', oauthRouter)
app.use('/calendar', calendarRoute)

// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404, 'route doesn\'t exist'))
next(createError(404, "route doesn't exist"))
})

// error handler
Expand Down
13 changes: 13 additions & 0 deletions app/models/GoogleUser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const mongoose = require('mongoose')
const Schema = mongoose.Schema

const googleUserSchema = new Schema({
username: String,
googleId: String,
token: String,
refreshToken: String
})

const GoogleUser = mongoose.model('googleuser', googleUserSchema)

module.exports = GoogleUser
142 changes: 142 additions & 0 deletions app/routes/calendar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
var express = require('express')
var router = express.Router()
var gcal = require('google-calendar')
const refresh = require('passport-oauth2-refresh')
const GoogleUser = require('../models/GoogleUser')
const tokenUtils = require('../utils/token-utils')

// POST
// /calendar/list
// Returns a list of calendar objects for a given user
router.post('/list', (req, res) => {
// const accessToken = req.body.token;
const googleId = req.body.googleId

tokenUtils.getToken(googleId).then(accessToken => {
const googleCalendar = new gcal.GoogleCalendar(accessToken)

googleCalendar.calendarList.list(function (err, data) {
if (err) {
GoogleUser.findOne({ googleId: googleId }, (err, user) => {
if (err) {
res.json(err)
}
const refreshToken = user.refreshToken
refresh.requestNewAccessToken('google', refreshToken, function (
_,
accessToken,
refreshToken
) {
user.token = accessToken
user.save().then(user => {
const googleCalendar1 = new gcal.GoogleCalendar(user.token)

googleCalendar1.calendarList.list((err, data) => {
if (err) {
res.json(err)
}
res.json(data)
})
})
})
})
} else {
return res.json(data)
}
})
})
})

// POST
// /calendar/events
// Returns a list of events for a given calendar
router.post('/events', (req, res) => {
const googleId = req.body.googleId
const id = req.body.id

tokenUtils.getToken(googleId).then(token => {
const googleCalendar = new gcal.GoogleCalendar(token)

googleCalendar.events.list(id, function (err, calendarList) {
if (err) {
GoogleUser.findOne({ googleId: googleId }, (err, user) => {
if (err) {
res.json(err)
}
const refreshToken = user.refreshToken
refresh.requestNewAccessToken('google', refreshToken, function (
_,
accessToken,
refreshToken
) {
user.token = accessToken
user.save().then(user => {
const googleCalendar1 = new gcal.GoogleCalendar(user.token)

googleCalendar1.events.list(id, (err, data) => {
if (err) {
res.json(err)
} else {
res.json(data)
console.log(data)
}
})
})
})
})
} else {
return res.json(calendarList)
}
})
})
})

// POST
// /calendar/newevent
// Creates a new event for the calendar id passed in
router.post('/newevent', (req, res) => {
const googleId = req.body.googleId

const id = req.body.id
const start = req.body.startDate
const end = req.body.endDate
const title = req.body.title
const params = {
start: { dateTime: start },
end: { dateTime: end },
summary: title
}

tokenUtils.getToken(googleId).then(token => {
const googleCalendar = new gcal.GoogleCalendar(token)
googleCalendar.events.insert(id, params, function (err, data) {
if (err) {
GoogleUser.findOne({ googleId: googleId }, (err, user) => {
if (err) {
res.json(err)
}
const refreshToken = user.refreshToken
refresh.requestNewAccessToken('google', refreshToken, function (
_,
accessToken,
refreshToken
) {
user.token = accessToken
user.save().then(user => {
const googleCalendar1 = new gcal.GoogleCalendar(user.token)

googleCalendar1.events.insert(id, params, (err, data) => {
if (err) res.json(err)
res.json(data)
})
})
})
})
} else {
return res.json(data)
}
})
})
})

module.exports = router
31 changes: 31 additions & 0 deletions app/routes/oauth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const express = require('express')
const router = express.Router()
const passport = require('passport')

// GET
// /oauth/google
router.get(
'/google',
passport.authenticate('google', {
scope: [
'https://www.googleapis.com/auth/plus.login',
'https://www.googleapis.com/auth/calendar'
],
prompt: 'consent',
accessType: 'offline'
})
)

// GET
// /oauth/callback
// Callback url MUST BE similar to one mentioned in the
router.get(
'/google/callback',
passport.authenticate('google', { failureRedirect: '/oauth/google' }),
function (req, res) {
const googleId = req.user.googleId
res.redirect('http://localhost:3000/calendar?googleId=' + googleId)
}
)

module.exports = router
10 changes: 10 additions & 0 deletions app/utils/token-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const GoogleUser = require('../models/GoogleUser')

module.exports = {
getToken: async googleId => {
const user = await GoogleUser.findOne({ googleId: googleId })
if (user) {
return user.token
}
}
}
55 changes: 53 additions & 2 deletions config/passport.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,53 @@
// TODO:
// YET TO IMPLEMENT WITH PASSPORT
const GoogleStrategy = require('passport-google-oauth20').Strategy
const GoogleUser = require('../app/models/GoogleUser')
const passport = require('passport')
const refresh = require('passport-oauth2-refresh')

passport.serializeUser(function (user, done) {
done(null, user.id)
})

passport.deserializeUser(function (id, done) {
GoogleUser.findById(id).then((user) => {
done(null, user)
})
})

const strategy = new GoogleStrategy(
{
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: process.env.GOOGLE_CLIENT_CALLBACKURL
},
(accessToken, refreshToken, profile, done) => {
GoogleUser.findOneAndUpdate(
{ googleId: profile.id },
{ token: accessToken, refreshToken: refreshToken },
{ new: true, upsert: true },
(err, currentUser) => {
if (err) {
done(null, false, { message: 'Error in findOneAndUpdate method' })
}
if (currentUser) {
done(null, currentUser)
} else {
new GoogleUser({
username: profile.displayName,
googleId: profile.id,
token: accessToken,
refreshToken: refreshToken
}).save((err, newUser) => {
if (err) {
done(null, false, { message: 'Error saving new user' })
} else {
done(null, newUser)
}
})
}
}
)
}
)

passport.use(strategy)
refresh.use(strategy)
Loading