Browse Source

fix: google oauth2.0 (#2080)

Signed-off-by: Vijay Kumar Rathore <professional.vijay8492@gmail.com>
pull/1687/head
Vijay Rathore 3 years ago committed by GitHub
parent
commit
36f1c2dd6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      packages/nocodb/src/lib/noco-models/Plugin.ts
  2. 86
      packages/nocodb/src/lib/noco/meta/api/userApi/initStrategies.ts
  3. 142
      packages/nocodb/src/lib/noco/meta/api/userApi/userApis.ts

15
packages/nocodb/src/lib/noco-models/Plugin.ts

@ -85,18 +85,25 @@ export default class Plugin implements PluginType {
}
public static async isPluginActive(title: string) {
const plugin =
return !!(await this.getPluginByTitle(title))?.active;
}
/**
* get plugin by title
*/
public static async getPluginByTitle(title: string) {
let plugin =
title &&
(await NocoCache.get(
`${CacheScope.PLUGIN}:${title}`,
CacheGetType.TYPE_OBJECT
));
if (!plugin) {
await Noco.ncMeta.metaGet2(null, null, MetaTable.PLUGIN, {
plugin = await Noco.ncMeta.metaGet2(null, null, MetaTable.PLUGIN, {
title
});
await NocoCache.set(`${CacheScope.PLUGIN}:${title}`, !!plugin?.active);
await NocoCache.set(`${CacheScope.PLUGIN}:${title}`, plugin);
}
return !!plugin?.active;
return plugin;
}
}

86
packages/nocodb/src/lib/noco/meta/api/userApi/initStrategies.ts

@ -7,6 +7,7 @@ import { Strategy } from 'passport-jwt';
import passport from 'passport';
import { ExtractJwt } from 'passport-jwt';
import { Strategy as AuthTokenStrategy } from 'passport-auth-token';
import { Strategy as GoogleStrategy } from 'passport-google-oauth20';
const PassportLocalStrategy = require('passport-local').Strategy;
@ -21,6 +22,7 @@ import NocoCache from '../../../../noco-cache/NocoCache';
import { CacheGetType, CacheScope } from '../../../../utils/globals';
import ApiToken from '../../../../noco-models/ApiToken';
import Noco from '../../../Noco';
import Plugin from '../../../../noco-models/Plugin';
export function initStrategies(router): void {
passport.use(
@ -188,5 +190,89 @@ export function initStrategies(router): void {
})
);
// mostly copied from older code
Plugin.getPluginByTitle('Google').then(googlePlugin => {
if (googlePlugin && googlePlugin.input) {
const settings = JSON.parse(googlePlugin.input);
process.env.NC_GOOGLE_CLIENT_ID = settings.client_id;
process.env.NC_GOOGLE_CLIENT_SECRET = settings.client_secret;
}
if (
process.env.NC_GOOGLE_CLIENT_ID &&
process.env.NC_GOOGLE_CLIENT_SECRET
) {
const googleAuthParamsOrig = GoogleStrategy.prototype.authorizationParams;
GoogleStrategy.prototype.authorizationParams = (options: any) => {
const params = googleAuthParamsOrig.call(this, options);
if (options.state) {
params.state = options.state;
}
return params;
};
const clientConfig = {
clientID: process.env.NC_GOOGLE_CLIENT_ID,
clientSecret: process.env.NC_GOOGLE_CLIENT_SECRET,
// todo: update url
callbackURL: 'http://localhost:3000',
passReqToCallback: true
};
const googleStrategy = new GoogleStrategy(
clientConfig,
async (req, _accessToken, _refreshToken, profile, done) => {
const email = profile.emails[0].value;
User.getByEmail(email)
.then(async user => {
if (req.ncProjectId) {
ProjectUser.get(req.ncProjectId, user.id)
.then(async projectUser => {
user.roles = projectUser?.roles || 'user';
user.roles =
user.roles === 'owner' ? 'owner,creator' : user.roles;
// + (user.roles ? `,${user.roles}` : '');
done(null, user);
})
.catch(e => done(e));
} else {
// const roles = projectUser?.roles ? JSON.parse(projectUser.roles) : {guest: true};
if (user) {
return done(null, user);
} else {
let roles = 'editor';
if (!(await User.isFirst())) {
roles = 'owner';
}
if (roles === 'editor') {
return done(new Error('User not found'));
}
const salt = await promisify(bcrypt.genSalt)(10);
user = await await User.insert({
email: profile.emails[0].value,
password: '',
salt,
roles,
email_verified: true
});
return done(null, user);
}
}
})
.catch(err => {
return done(err);
});
}
);
passport.use(googleStrategy);
}
});
router.use(passport.initialize());
}

142
packages/nocodb/src/lib/noco/meta/api/userApi/userApis.ts

@ -156,57 +156,93 @@ export async function signup(req: Request, res: Response<TableType>) {
} as any);
}
async function successfulSignIn({
user,
err,
info,
req,
res,
auditDescription
}) {
try {
if (!user || !user.email) {
if (err) {
return res.status(400).send(err);
}
if (info) {
return res.status(400).send(info);
}
return res.status(400).send({ msg: 'Your signin has failed' });
}
await promisify((req as any).login.bind(req))(user);
const refreshToken = randomTokenString();
await User.update(user.id, {
refresh_token: refreshToken
});
setTokenCookie(res, refreshToken);
Audit.insert({
op_type: 'AUTHENTICATION',
op_sub_type: 'SIGNIN',
user: user.email,
ip: req.clientIp,
description: auditDescription
});
res.json({
token: jwt.sign(
{
email: user.email,
firstname: user.firstname,
lastname: user.lastname,
id: user.id,
roles: user.roles
},
Noco.getConfig().auth.jwt.secret,
Noco.getConfig().auth.jwt.options
)
} as any);
} catch (e) {
console.log(e);
throw e;
}
}
async function signin(req, res, next) {
passport.authenticate(
'local',
{ session: false },
async (err, user, info): Promise<any> => {
try {
if (!user || !user.email) {
if (err) {
return res.status(400).send(err);
}
if (info) {
return res.status(400).send(info);
}
return res.status(400).send({ msg: 'Your signin has failed' });
}
await promisify((req as any).login.bind(req))(user);
const refreshToken = randomTokenString();
await User.update(user.id, {
refresh_token: refreshToken
});
setTokenCookie(res, refreshToken);
Audit.insert({
op_type: 'AUTHENTICATION',
op_sub_type: 'SIGNIN',
user: user.email,
ip: req.clientIp,
description: `signed in`
});
res.json({
token: jwt.sign(
{
email: user.email,
firstname: user.firstname,
lastname: user.lastname,
id: user.id,
roles: user.roles
},
Noco.getConfig().auth.jwt.secret,
Noco.getConfig().auth.jwt.options
)
} as any);
} catch (e) {
console.log(e);
throw e;
}
}
async (err, user, info): Promise<any> =>
await successfulSignIn({
user,
err,
info,
req,
res,
auditDescription: 'signed in'
})
)(req, res, next);
}
async function googleSignin(req, res, next) {
passport.authenticate(
'google',
{
session: false,
callbackURL: req.ncSiteUrl + Noco.getConfig().dashboardPath
},
async (err, user, info): Promise<any> =>
await successfulSignIn({
user,
err,
info,
req,
res,
auditDescription: 'signed in using Google Auth'
})
)(req, res, next);
}
@ -461,6 +497,18 @@ const mapRoutes = router => {
);
router.post('/auth/token/refresh', ncMetaAclMw(refreshToken, 'refreshToken'));
/* Google auth apis */
router.post(`/auth/google/genTokenByCode`, catchError(googleSignin));
router.get('/auth/google', (req: any, res, next) =>
passport.authenticate('google', {
scope: ['profile', 'email'],
state: req.query.state,
callbackURL: req.ncSiteUrl + Noco.getConfig().dashboardPath
})(req, res, next)
);
// new API
router.post('/api/v1/db/auth/user/signup', catchError(signup));
router.post('/api/v1/db/auth/user/signin', catchError(signin));

Loading…
Cancel
Save