google auth E2E
This commit is contained in:
parent
301f681c88
commit
ffe167bbd3
|
@ -70,12 +70,11 @@ exports.getUserParams = (email = "", otherProps = {}) => {
|
|||
* Generates a new configuration ID.
|
||||
* @returns {string} The new configuration ID which the config doc can be stored under.
|
||||
*/
|
||||
exports.generateConfigID = (type = "", group = "") => {
|
||||
group += SEPARATOR
|
||||
exports.generateConfigID = (type = "", group = "", user = "") => {
|
||||
// group += SEPARATOR
|
||||
const scope = [type, group, user].join(SEPARATOR)
|
||||
|
||||
return `${
|
||||
DocumentTypes.CONFIG
|
||||
}${SEPARATOR}${type}${SEPARATOR}${group}${newid()}`
|
||||
return `${DocumentTypes.CONFIG}${SEPARATOR}${scope}${newid()}`
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
const passport = require("koa-passport")
|
||||
const LocalStrategy = require("passport-local").Strategy
|
||||
const JwtStrategy = require("passport-jwt").Strategy
|
||||
// const GoogleStrategy = require("passport-google-oauth").Strategy
|
||||
const GoogleStrategy = require("passport-google-oauth").OAuth2Strategy
|
||||
const database = require("./db")
|
||||
const { StaticDatabases } = require("./db/utils")
|
||||
const { jwt, local, authenticated } = require("./middleware")
|
||||
const { StaticDatabases, DocumentTypes } = require("./db/utils")
|
||||
const { jwt, local, google, authenticated } = require("./middleware")
|
||||
const { Cookies, UserStatus } = require("./constants")
|
||||
const { hash, compare } = require("./hashing")
|
||||
const {
|
||||
|
@ -27,7 +27,7 @@ const {
|
|||
// Strategies
|
||||
passport.use(new LocalStrategy(local.options, local.authenticate))
|
||||
passport.use(new JwtStrategy(jwt.options, jwt.authenticate))
|
||||
// passport.use(new GoogleStrategy(google.options, google.authenticate))
|
||||
passport.use(new GoogleStrategy(google.options, google.authenticate))
|
||||
|
||||
passport.serializeUser((user, done) => done(null, user))
|
||||
|
||||
|
@ -50,6 +50,7 @@ module.exports = {
|
|||
passport,
|
||||
Cookies,
|
||||
UserStatus,
|
||||
DocumentTypes,
|
||||
StaticDatabases,
|
||||
generateUserID,
|
||||
getUserParams,
|
||||
|
|
|
@ -1,18 +1,54 @@
|
|||
const env = require("../../environment")
|
||||
const jwt = require("jsonwebtoken")
|
||||
const database = require("../../db")
|
||||
const { StaticDatabases, generateUserID } = require("../../db/utils")
|
||||
|
||||
exports.options = {
|
||||
clientId: env.GOOGLE_CLIENT_ID,
|
||||
clientID: env.GOOGLE_CLIENT_ID,
|
||||
clientSecret: env.GOOGLE_CLIENT_SECRET,
|
||||
callbackURL: env.GOOGLE_AUTH_CALLBACK_URL,
|
||||
}
|
||||
|
||||
exports.authenticate = async function(token, tokenSecret, profile, done) {
|
||||
console.log({
|
||||
token,
|
||||
tokenSecret,
|
||||
profile,
|
||||
done,
|
||||
if (!profile._json.email) return done(null, false, "Email Required.")
|
||||
|
||||
// Check the user exists in the instance DB by email
|
||||
const db = new database.CouchDB(StaticDatabases.GLOBAL.name)
|
||||
|
||||
let dbUser
|
||||
const userId = generateUserID(profile._json.email)
|
||||
|
||||
try {
|
||||
// use the google profile id
|
||||
dbUser = await db.get(userId)
|
||||
} catch (err) {
|
||||
console.error("Google user not found. Creating..")
|
||||
// create the user
|
||||
const user = {
|
||||
_id: userId,
|
||||
provider: profile.provider,
|
||||
roles: {},
|
||||
builder: {
|
||||
global: true,
|
||||
},
|
||||
...profile._json,
|
||||
}
|
||||
const response = await db.post(user)
|
||||
|
||||
dbUser = user
|
||||
dbUser._rev = response.rev
|
||||
}
|
||||
|
||||
// authenticate
|
||||
const payload = {
|
||||
userId: dbUser._id,
|
||||
builder: dbUser.builder,
|
||||
email: dbUser.email,
|
||||
}
|
||||
|
||||
dbUser.token = jwt.sign(payload, env.JWT_SECRET, {
|
||||
expiresIn: "1 day",
|
||||
})
|
||||
// retrieve user ...
|
||||
// fetchUser().then(user => done(null, user))
|
||||
|
||||
return done(null, dbUser)
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
<Input outline type="password" on:change bind:value={password} />
|
||||
<Spacer large />
|
||||
<Button primary on:click={login}>Login</Button>
|
||||
<a target="_blank" href="/api/admin/auth/google">Sign In with Google</a>
|
||||
<Button secondary on:click={createTestUser}>Create Test User</Button>
|
||||
</form>
|
||||
|
||||
|
|
|
@ -1,17 +1,47 @@
|
|||
const CouchDB = require("../../../db")
|
||||
const { StaticDatabases } = require("@budibase/auth")
|
||||
const { generateConfigID } = require("@budibase/auth")
|
||||
const { getConfigParams } = require("@budibase/auth/src/db/utils")
|
||||
const { StaticDatabases, DocumentTypes } = require("@budibase/auth")
|
||||
const { generateConfigID, getConfigParams } = require("@budibase/auth")
|
||||
const { SEPARATOR } = require("@budibase/auth/src/db/utils")
|
||||
const { Configs } = require("../../../constants")
|
||||
|
||||
const GLOBAL_DB = StaticDatabases.GLOBAL.name
|
||||
|
||||
exports.configStatus = async function(ctx) {
|
||||
const db = new CouchDB(GLOBAL_DB)
|
||||
let configured = {}
|
||||
|
||||
// check for super admin user
|
||||
try {
|
||||
configured.user = true
|
||||
} catch (err) {
|
||||
configured.user = false
|
||||
}
|
||||
|
||||
// check for SMTP config
|
||||
try {
|
||||
const response = await db.allDocs(
|
||||
getConfigParams(`${DocumentTypes.CONFIG}${SEPARATOR}${Configs.SMTP}`)
|
||||
)
|
||||
console.log(response)
|
||||
configured.smtp = true
|
||||
} catch (err) {
|
||||
configured.smtp = false
|
||||
}
|
||||
|
||||
ctx.body = configured
|
||||
}
|
||||
|
||||
exports.save = async function(ctx) {
|
||||
const db = new CouchDB(GLOBAL_DB)
|
||||
const configDoc = ctx.request.body
|
||||
|
||||
// Config does not exist yet
|
||||
if (!configDoc._id) {
|
||||
configDoc._id = generateConfigID(configDoc.type, configDoc.group)
|
||||
configDoc._id = generateConfigID(
|
||||
configDoc.type,
|
||||
configDoc.group,
|
||||
configDoc.user
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
@ -1,4 +1,38 @@
|
|||
const { passport, Cookies, clearCookie } = require("@budibase/auth")
|
||||
const {
|
||||
passport,
|
||||
Cookies,
|
||||
StaticDatabases,
|
||||
clearCookie,
|
||||
} = require("@budibase/auth")
|
||||
const CouchDB = require("../../db")
|
||||
|
||||
const GLOBAL_DB = StaticDatabases.GLOBAL.name
|
||||
|
||||
async function setToken(ctx) {
|
||||
return async function(err, user) {
|
||||
if (err) {
|
||||
return ctx.throw(403, "Unauthorized")
|
||||
}
|
||||
|
||||
const expires = new Date()
|
||||
expires.setDate(expires.getDate() + 1)
|
||||
|
||||
if (!user) {
|
||||
return ctx.throw(403, "Unauthorized")
|
||||
}
|
||||
|
||||
ctx.cookies.set(Cookies.Auth, user.token, {
|
||||
expires,
|
||||
path: "/",
|
||||
httpOnly: false,
|
||||
overwrite: true,
|
||||
})
|
||||
|
||||
delete user.token
|
||||
|
||||
ctx.body = { user }
|
||||
}
|
||||
}
|
||||
|
||||
exports.authenticate = async (ctx, next) => {
|
||||
return passport.authenticate("local", async (err, user) => {
|
||||
|
@ -31,10 +65,30 @@ exports.logout = async ctx => {
|
|||
ctx.body = { message: "User logged out" }
|
||||
}
|
||||
|
||||
exports.googleAuth = async () => {
|
||||
// return passport.authenticate("google")
|
||||
}
|
||||
exports.googleAuth = async (ctx, next) => {
|
||||
return passport.authenticate(
|
||||
"google",
|
||||
{ successRedirect: "/", failureRedirect: "/" },
|
||||
async (err, user) => {
|
||||
if (err) {
|
||||
return ctx.throw(403, "Unauthorized")
|
||||
}
|
||||
|
||||
exports.googleAuth = async () => {
|
||||
// return passport.authenticate("google")
|
||||
const expires = new Date()
|
||||
expires.setDate(expires.getDate() + 1)
|
||||
|
||||
if (!user) {
|
||||
return ctx.throw(403, "Unauthorized")
|
||||
}
|
||||
|
||||
ctx.cookies.set(Cookies.Auth, user.token, {
|
||||
expires,
|
||||
path: "/",
|
||||
httpOnly: false,
|
||||
overwrite: true,
|
||||
})
|
||||
|
||||
ctx.redirect("/")
|
||||
}
|
||||
)(ctx, next)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ const router = Router()
|
|||
function buildConfigSaveValidation() {
|
||||
// prettier-ignore
|
||||
return joiValidator.body(Joi.object({
|
||||
type: Joi.string().valid(...Object.values(Configs)).required()
|
||||
type: Joi.string().valid(...Object.values(Configs)).required(),
|
||||
}).required().unknown(true))
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ router
|
|||
authenticated,
|
||||
controller.save
|
||||
)
|
||||
.post("/api/admin/config/status", controller.configStatus)
|
||||
.delete("/api/admin/configs/:id", authenticated, controller.destroy)
|
||||
.get("/api/admin/configs", authenticated, controller.fetch)
|
||||
.get("/api/admin/configs/:id", authenticated, controller.find)
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
const Router = require("@koa/router")
|
||||
const { passport } = require("@budibase/auth")
|
||||
const authController = require("../controllers/auth")
|
||||
const context = require("koa/lib/context")
|
||||
|
||||
const router = Router()
|
||||
|
||||
router
|
||||
.post("/api/admin/auth", authController.authenticate)
|
||||
.post("/api/admin/auth/logout", authController.logout)
|
||||
.get("/api/auth/google", passport.authenticate("google"))
|
||||
.get(
|
||||
"/api/auth/google/callback",
|
||||
passport.authenticate("google", {
|
||||
successRedirect: "/app",
|
||||
failureRedirect: "/",
|
||||
})
|
||||
"/api/admin/auth/google",
|
||||
passport.authenticate("google", { scope: ["profile", "email"] })
|
||||
)
|
||||
.get("/api/admin/auth/google/callback", authController.googleAuth)
|
||||
.post("/api/admin/auth/logout", authController.logout)
|
||||
|
||||
module.exports = router
|
||||
|
|
Loading…
Reference in New Issue