diff --git a/package-lock.json b/package-lock.json index 0289a8e..3851013 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1278,6 +1278,15 @@ "integrity": "sha512-qAfo81CsD7yQIM9mVyh6B/U47li5g7cfpVQEDMfQeF8pSZVwzbhwU3crc0qG4DmpsebpJPR49AKOExQyJ05Cpg==", "dev": true }, + "@types/oauth": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.1.tgz", + "integrity": "sha512-a1iY62/a3yhZ7qH7cNUsxoI3U/0Fe9+RnuFrpTKr+0WVOzbKlSLojShCKe20aOD1Sppv+i8Zlq0pLDuTJnwS4A==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/passport": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.4.tgz", @@ -1297,6 +1306,28 @@ "@types/passport": "*" } }, + "@types/passport-google-oauth20": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.4.tgz", + "integrity": "sha512-lYLsLzbYKlCopSO1b/FdxsBOgpIIZfvhVdVj5Wgx97udiPDGqv3g8Sq5OsWk20idtPL606SnfPRFgWfx698Nkw==", + "dev": true, + "requires": { + "@types/express": "*", + "@types/passport": "*", + "@types/passport-oauth2": "*" + } + }, + "@types/passport-oauth2": { + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.4.9.tgz", + "integrity": "sha512-QP0q+NVQOaIu2r0e10QWkiUA0Ya5mOBHRJN0UrI+LolMLOP1/VN4EVIpJ3xVwFo+xqNFRoFvFwJhBvKnk7kpUA==", + "dev": true, + "requires": { + "@types/express": "*", + "@types/oauth": "*", + "@types/passport": "*" + } + }, "@types/passport-twitter": { "version": "1.0.36", "resolved": "https://registry.npmjs.org/@types/passport-twitter/-/passport-twitter-1.0.36.tgz", diff --git a/package.json b/package.json index c013d83..c105a53 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "@types/node": "^12.11.6", "@types/passport": "^1.0.4", "@types/passport-facebook": "^2.1.10", + "@types/passport-google-oauth20": "^2.0.4", "@types/passport-twitter": "^1.0.36", "@types/react": "^16.9.11", "@types/react-dom": "^16.9.4", diff --git a/server/auth/passport.ts b/server/auth/passport.ts index ff43ae1..66f3e88 100644 --- a/server/auth/passport.ts +++ b/server/auth/passport.ts @@ -1,6 +1,7 @@ import passport from 'passport'; import { facebookStrategy, facebookRouter } from './providers/facebook'; import { twitterStrategy, twitterRouter } from './providers/twitter'; +import { googleStrategy, googleRouter } from './providers/google'; import { Router } from 'express' import UserModel, { User } from '../models/user' @@ -17,8 +18,10 @@ export function initPassport(): void { passport.use('facebook', facebookStrategy()); passport.use('twitter', twitterStrategy()); + passport.use('google', googleStrategy()); } export const authRouter = Router(); authRouter.use(facebookRouter); authRouter.use(twitterRouter); +authRouter.use(googleRouter); diff --git a/server/auth/providers/google.ts b/server/auth/providers/google.ts new file mode 100644 index 0000000..771c7b2 --- /dev/null +++ b/server/auth/providers/google.ts @@ -0,0 +1,27 @@ +import { Strategy, Profile, StrategyOptions, AuthenticateOptionsGoogle } from 'passport-google-oauth20'; + +import { Router } from 'express' +import passport from 'passport' + +import genericStrategy from '../strategy' + +const strategyOptions: StrategyOptions = { + clientID: process.env.GOOGLE_CLIENT_ID as string, + clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, + callbackURL: '/auth/google/redirect', +} + +export function googleStrategy() { + // @ts-ignore: No overload matches this call. + return new Strategy(strategyOptions, genericStrategy('google')); +} + +export const googleRouter = Router() + +const googleAuthenticateOptions: AuthenticateOptionsGoogle = { + scope: ['email', 'profile'] +} + +googleRouter.get('/google', passport.authenticate('google', googleAuthenticateOptions)); +googleRouter.get('/google/redirect', + passport.authenticate('google', { successRedirect: '/museo', failureRedirect: '/' })); diff --git a/server/auth/strategy.ts b/server/auth/strategy.ts index df7f80d..bfe8e48 100644 --- a/server/auth/strategy.ts +++ b/server/auth/strategy.ts @@ -35,7 +35,7 @@ function genericStrategy(provider: au name: profile.displayName, provider, email: profile.emails?.[0].value, - photo: profile.photos?.[0].value.replace('_normal', ''), + photo: profile.photos?.[0].value.replace('_normal', '').replace('=s96-c', ''), }).save((err: string) => { if (err) throw (err); }); diff --git a/tsconfig.json b/tsconfig.json index bcbf8fb..4362108 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,7 +14,7 @@ "skipLibCheck": true, "esModuleInterop": true, "isolatedModules": true, - "allowSyntheticDefaultImports": true, + "allowSyntheticDefaultImports": true }, "exclude": [ "node_modules", diff --git a/views/index.tsx b/views/index.tsx index 8d2831a..123647c 100644 --- a/views/index.tsx +++ b/views/index.tsx @@ -9,6 +9,7 @@ const Index: React.FC = () => { Autenticarse con Facebook Autenticarse con Twitter + Autenticarse con Google ); };