feat: github auth

This commit is contained in:
Annie Huang committed 2023-10-12 16:12:07 +08:00
1 parent 8719591faa
commit ad5344c98b
14 files changed
+127 -2

No files matched your search

+2
View File
@@ -40,6 +40,8 @@ jobs:
env:
GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }}
GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }}
GITHUB_CLIENT_ID: ${{ secrets.GITHUB_CLIENT_ID }}
GITHUB_CLIENT_SECRET: ${{ secrets.GITHUB_CLIENT_SECRET }}
run: docker-compose -f docker-compose.testing.yml run cypress
- name: Tear Down Test Environment
@@ -191,6 +191,13 @@ const goBack = () => {
>
<span>Google</span>
</a>
<a
v-if="availableMethods.github"
class="inline-flex justify-center rounded-lg text-sm font-black py-2 mt-3 bg-icon-github text-text w-full"
href="/api/v1/auth/github"
>
<span>Github</span>
</a>
</div>
</form>
</div>
+1
View File
@@ -24,6 +24,7 @@ export default {
},
icon: {
google: '#DB4437',
github: '#171515',
},
},
},
+2
View File
@@ -44,6 +44,8 @@ services:
- MONGO_DB=odyssey-test
- GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}
- GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}
- GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID}
- GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET}
base:
image: lancatlin/linux-odyssey:base
+2
View File
@@ -42,6 +42,8 @@ services:
- DOCKER_NETWORK=linux-odyssey-players
- GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}
- GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}
- GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID}
- GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET}
db-test:
image: mongo
+2
View File
@@ -33,6 +33,8 @@ services:
- HOST_PWD=${PWD}
- GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}
- GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}
- GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID}
- GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET}
db:
image: mongo
networks:
+3 -1
View File
@@ -1,2 +1,4 @@
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_CLIENT_SECRET=
GITHUB_CLIENT_ID=
GITNUB_CLIENT_SECRET=
+1
View File
@@ -22,6 +22,7 @@
"mongoose": "^7.4.0",
"node-schedule": "^2.1.1",
"passport": "^0.6.0",
"passport-github2": "^0.1.12",
"passport-google-oidc": "^0.1.0",
"passport-jwt": "^4.0.1",
"passport-local": "^1.0.0",
+11
View File
@@ -43,4 +43,15 @@ if (enabledMethods.google) {
)
}
if (enabledMethods.github) {
router.get('/github', passport.authenticate('github'))
router.get(
'/github/callback',
passport.authenticate('github', {
successRedirect: '/',
failureRedirect: '/login',
})
)
}
export default router
+53
View File
@@ -0,0 +1,53 @@
import GitHubStrategy from 'passport-github2'
import config from '../config.js'
import User from '../models/user.js'
function verify(accessToken, refreshToken, profile, cb) {
process.nextTick(async () => {
console.log(accessToken, refreshToken, profile)
// cb('todo')
const email = profile.emails[0]?.value
if (!email) {
cb(new Error('No email found'))
return
}
let user = await User.findOne({ 'github.id': profile.id })
if (!user) {
user = await User.findOne({ email })
const github = {
id: profile.id,
displayName: profile.displayName,
}
if (!user) {
user = new User({
email,
github,
})
} else if (user.github?.id) {
cb(new Error('Email already used and binded to another account'))
return
} else {
user.github = github
}
await user.save()
}
cb(null, user)
})
}
const enabled = config.github.clientID && config.github.clientSecret
export default enabled
? new GitHubStrategy(
{
clientID: config.github.clientID,
clientSecret: config.github.clientSecret,
callbackURL: `${config.baseUrl}/api/v1/auth/github/callback`,
scope: ['user:email'],
},
verify
)
: null
+6
View File
@@ -2,6 +2,7 @@ import passport from 'passport'
import passwordStrategy from './passwordStrategy.js'
import jwtStrategy from './jwtStrategy.js'
import googleStrategy from './googleStrategy.js'
import githubStrategy from './githubStrategy.js'
passport.use(passwordStrategy)
passport.use(jwtStrategy)
@@ -9,6 +10,7 @@ passport.use(jwtStrategy)
const enabledMethods = {
local: true,
google: googleStrategy !== null,
github: githubStrategy !== null,
}
console.log('Enabled login methods', enabledMethods)
@@ -17,6 +19,10 @@ if (enabledMethods.google) {
passport.use(googleStrategy)
}
if (enabledMethods.github) {
passport.use(githubStrategy)
}
passport.serializeUser((user, done) => {
process.nextTick(() => {
done(null, {
+4
View File
@@ -14,6 +14,10 @@ const config = {
clientID: get('GOOGLE_CLIENT_ID', ''),
clientSecret: get('GOOGLE_CLIENT_SECRET', ''),
},
github: {
clientID: get('GITHUB_CLIENT_ID', ''),
clientSecret: get('GITHUB_CLIENT_SECRET', ''),
},
}
config.baseUrl = get('BASE_URL', `http://${config.host}:${config.port}`)
+4
View File
@@ -17,6 +17,10 @@ const User = model('User', {
id: String,
displayName: String,
},
github: {
id: String,
displayName: String,
},
})
export default User
+29 -1
View File
@@ -1448,6 +1448,11 @@ base64id@2.0.0, base64id@~2.0.0:
resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6"
integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==
base64url@3.x.x:
version "3.0.1"
resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d"
integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==
bcrypt-pbkdf@^1.0.0, bcrypt-pbkdf@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
@@ -4664,6 +4669,13 @@ parseurl@~1.3.3:
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
passport-github2@^0.1.12:
version "0.1.12"
resolved "https://registry.yarnpkg.com/passport-github2/-/passport-github2-0.1.12.tgz#a72ebff4fa52a35bc2c71122dcf470d1116f772c"
integrity sha512-3nPUCc7ttF/3HSP/k9sAXjz3SkGv5Nki84I05kSQPo01Jqq1NzJACgMblCK0fGcv9pKCG/KXU3AJRDGLqHLoIw==
dependencies:
passport-oauth2 "1.x.x"
passport-google-oidc@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/passport-google-oidc/-/passport-google-oidc-0.1.0.tgz#585790ba03864c0238cb89912d7e2a958086b5b0"
@@ -4686,6 +4698,17 @@ passport-local@^1.0.0:
dependencies:
passport-strategy "1.x.x"
passport-oauth2@1.x.x:
version "1.7.0"
resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.7.0.tgz#5c4766c8531ac45ffe9ec2c09de9809e2c841fc4"
integrity sha512-j2gf34szdTF2Onw3+76alNnaAExlUmHvkc7cL+cmaS5NzHzDP/BvFHJruueQ9XAeNOdpI+CH+PWid8RA7KCwAQ==
dependencies:
base64url "3.x.x"
oauth "0.9.x"
passport-strategy "1.x.x"
uid2 "0.0.x"
utils-merge "1.x.x"
passport-openidconnect@0.1.x:
version "0.1.1"
resolved "https://registry.yarnpkg.com/passport-openidconnect/-/passport-openidconnect-0.1.1.tgz#83921ff5f87f634079f65262dada834af1972244"
@@ -5775,6 +5798,11 @@ uid-safe@~2.1.5:
dependencies:
random-bytes "~1.0.0"
uid2@0.0.x:
version "0.0.4"
resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.4.tgz#033f3b1d5d32505f5ce5f888b9f3b667123c0a44"
integrity sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==
unbox-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
@@ -5838,7 +5866,7 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2:
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
utils-merge@1.0.1, utils-merge@^1.0.1:
utils-merge@1.0.1, utils-merge@1.x.x, utils-merge@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==