mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-06 03:20:13 +08:00
feat: github auth
This commit is contained in:
1 parent
8719591faa
commit
ad5344c98b
14 files changed
+127
-2
No files matched your search
@@ -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>
|
||||
|
||||
@@ -24,6 +24,7 @@ export default {
|
||||
},
|
||||
icon: {
|
||||
google: '#DB4437',
|
||||
github: '#171515',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -1,2 +1,4 @@
|
||||
GOOGLE_CLIENT_ID=
|
||||
GOOGLE_CLIENT_SECRET=
|
||||
GOOGLE_CLIENT_SECRET=
|
||||
GITHUB_CLIENT_ID=
|
||||
GITNUB_CLIENT_SECRET=
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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, {
|
||||
|
||||
@@ -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}`)
|
||||
|
||||
@@ -17,6 +17,10 @@ const User = model('User', {
|
||||
id: String,
|
||||
displayName: String,
|
||||
},
|
||||
github: {
|
||||
id: String,
|
||||
displayName: String,
|
||||
},
|
||||
})
|
||||
|
||||
export default User
|
||||
@@ -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==
|
||||
|
||||
Reference in new issue
Block a user