Skip to content

Instantly share code, notes, and snippets.

@JesseVelden
Last active January 23, 2026 14:04
Show Gist options
  • Select an option

  • Save JesseVelden/e11aaf876d9409b560f873bd156564ab to your computer and use it in GitHub Desktop.

Select an option

Save JesseVelden/e11aaf876d9409b560f873bd156564ab to your computer and use it in GitHub Desktop.
Retrieve JWT to Vault JSON

Usable by just using npx:

# Just start listening on http://localhost:12765/ext-login 
npx https://gist.github.com/JesseVelden/e11aaf876d9409b560f873bd156564ab

# Also opening an external link, and not displaying a startup message:
npx https://gist.github.com/JesseVelden/e11aaf876d9409b560f873bd156564ab -s -u https://example.com?callback=http://localhost:12765/ext-login
#!/usr/bin/env node
import { spawn } from 'node:child_process';
import * as http from 'node:http';
function isUrl(str) {
try {
new URL(str);
return true;
} catch {
return false;
}
}
let silentMode = false;
const args = process.argv.slice(2); // Skip 'node' and script path
for (let i = 0; i < args.length; i++) {
const arg = args[i];
const value = args[i + 1];
if (arg === '-u' && value !== undefined && isUrl(value)) {
// On Windows, 'start' opens the default browser
spawn(`start "" "${value}"`, { shell: true, stdio: 'ignore', detached: true });
i++;
} else if (arg === '-s') {
silentMode = true;
}
}
const LOCAL_JWT_REDIRECT_PORT = 12765;
async function retrieveJwtInteractive() {
return new Promise((resolve, reject) => {
const server = http.createServer(async (req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
if (req.method === 'OPTIONS') {
res.writeHead(204); // No content
res.end();
return;
}
const requestUrl = new URL(req.url || '', `http://localhost:${LOCAL_JWT_REDIRECT_PORT}`);
if (requestUrl.pathname === '/ext-login') {
let body = '';
req.on('data', (chunk) => {
body += chunk.toString();
});
req.on('end', () => {
try {
const jsonBody = JSON.parse(body);
const jwt = jsonBody.jwt;
if (jwt) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Login success! You can close this window now.');
server.close(() => {
resolve(jwt);
});
} else {
const errMessage = 'Could not find JWT in the request body.';
console.error(errMessage);
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end(errMessage);
reject(new Error(errMessage));
}
} catch (error) {
const errMessage = 'Error in processing the JSON body.';
console.error(errMessage, error);
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end(errMessage);
reject(new Error(errMessage));
}
});
} else {
res.writeHead(404);
res.end();
}
});
server.listen(LOCAL_JWT_REDIRECT_PORT, async () => {
if (!silentMode) console.debug(`Local login HTTP server started on port ${LOCAL_JWT_REDIRECT_PORT}.`);
});
server.on('error', (err) => {
console.error('Error at local login HTTP server.', err);
reject(err);
});
});
}
retrieveJwtInteractive().then(jwt => {
const result = {
data: {
username: '',
password: jwt,
},
};
console.log(JSON.stringify(result, null, 2));
});
{
"name": "@jessevelden/retrieve-jwt-to-vault-json",
"version": "1.0.0",
"type": "module",
"bin": "./index.js"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment