Created
May 18, 2022 12:46
-
-
Save anderson-marques/4ba5a5f03172e55fe48e3e23d55c44bc to your computer and use it in GitHub Desktop.
OpenID Connect Login to Gitlab using JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const http = require('http'); | |
const GITLAB_OAUTH_AUTHORIZATION_URL = 'https://gitlab.com/oauth/authorize' | |
const GITLAB_OAUTH_CLIENT_ID = 'change-me' | |
const SERVER_PORT = 4321 | |
let config = { | |
'base_url': GITLAB_OAUTH_AUTHORIZATION_URL, | |
'client_id': GITLAB_OAUTH_CLIENT_ID, | |
'redirect_uri': `http://localhost:${SERVER_PORT}/cb`, | |
'authentication_uri': `http://localhost:${SERVER_PORT}/auth`, | |
'state': Math.floor(Math.random() * 999999), | |
'scope': 'openid%20profile%20email', | |
} | |
let server; | |
const log = (m, ...o) => console.log(m, ...o); | |
const deviceLoginPage = ` | |
<body style="font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif"> | |
<script> | |
let originalHash = window.location.hash; | |
window.location.hash = ''; | |
let accessToken; | |
let tokenType; | |
let state; | |
if (originalHash.split('#').length == 2) { | |
for (var param of originalHash.split('#')[1].split('&')){ | |
let paramName = param.split('=')[0] | |
let paramValue = param.split('=')[1] | |
console.log(paramName, ' ', paramValue ) | |
if (paramName === 'access_token'){ | |
accessToken = paramValue; | |
} | |
if (paramName === 'token_type'){ | |
tokenType = paramValue; | |
} | |
if (paramName === 'state'){ | |
state = paramValue; | |
} | |
} | |
} | |
if (accessToken && state) { | |
fetch( | |
'auth', | |
{ | |
method: 'post', | |
headers: { | |
"Content-type": "application/json; charset=UTF-8" | |
}, | |
body: JSON.stringify({ "accessToken": accessToken, "state": state }) | |
} | |
).then(()=> console.log('Request succeeded!')).catch((error) => console.log('Request failed', error)); | |
setTimeout(window.close, 1000) | |
} else { | |
let title = document.createElement('h4'); | |
title.textContent = 'Invalid authentication request!' | |
} | |
</script> | |
</body> | |
` | |
const terminate = () => { | |
server.close() | |
setImmediate(()=> server.emit('close')) | |
process.exit(0) | |
} | |
const requestListener = function (req, res) { | |
if (req.url.startsWith('/cb') && req.method === 'GET') { | |
res.setHeader('Cache-Control', 'no-cache, no-store, max-age=0') | |
res.writeHead(200); | |
res.end(deviceLoginPage); | |
} | |
if (req.url.startsWith('/auth') && req.method === 'POST') { | |
let body = ''; | |
req.on('data', chunk => { | |
body += chunk; | |
}); | |
req.on('end', () => { | |
res.end(); | |
authentication = JSON.parse(body) | |
var accessToken = authentication.accessToken | |
var state = authentication.state | |
if(accessToken && state && String(state) == String(config.state)) { | |
log("\nSuccessfully authenticated!") | |
terminate() | |
} else { | |
log("\nAuthentication failed!") | |
terminate() | |
} | |
}); | |
} | |
} | |
const login = ()=> { | |
base_url = config['base_url'] | |
client_id = config['client_id'] | |
redirect_uri = config['redirect_uri'] | |
state = config['state'] | |
scope = config['scope'] | |
login_url = `${base_url}?client_id=${client_id}&redirect_uri=${redirect_uri}&response_type=token&state=${state}&scope=${scope}` | |
log(`\nClick or copy and paste this link in your browser: \n\n${login_url}`) | |
server = http.createServer(requestListener); | |
server.listen(SERVER_PORT); | |
} | |
login(config) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment