Skip to content

Instantly share code, notes, and snippets.

@anderson-marques
Created May 18, 2022 12:46
Show Gist options
  • Save anderson-marques/4ba5a5f03172e55fe48e3e23d55c44bc to your computer and use it in GitHub Desktop.
Save anderson-marques/4ba5a5f03172e55fe48e3e23d55c44bc to your computer and use it in GitHub Desktop.
OpenID Connect Login to Gitlab using JavaScript
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