|
#!/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)); |
|
}); |