1
0
Fork 0
forked from OpenNeo/impress
impress/bin/neopass-server
Emi Matchu 9cbeee0acd Refactor to use OpenID Connect OmniAuth gem instead of plain OAuth2
Right, I didn't totally connect the dots that there's some OpenID
features in the mix here for how we expect to identify the user once
they authenticate. It requires looking up the provider's public key,
and validating the JWT they sent us. This gem does all that for us!

I don't actually know what a real NeoPass `id_token` looks like yet?
But I'll fill in some placeholder stuff for now, and use that for
initializing the account!
2024-03-14 18:11:40 -07:00

103 lines
4.1 KiB
JavaScript
Executable file

#!/usr/bin/env node
/**
* A test NeoPass server! This is a very lean, hacky implementation, designed
* to just see the basic OAuth interactions Work At All.
*
* This server is an `oauth2-mock-server` instance that's easy to spin up and
* have perform OAuth for us. We give it a hardcoded development-only key, and
* it just auto-grants permissions!
*
* It slightly differs from the NeoPass spec, in that it uses different paths
* for its endpoints, but that's okay: DTI will use OpenID's "discovery"
* feature to discover those endpoints via a single well-known path, without
* needing them hardcoded.
*/
const fs = require("node:fs/promises");
const pathLib = require("node:path");
const { spawn } = require("node:child_process");
const urlLib = require("node:url");
const { OAuth2Server } = require("oauth2-mock-server");
const express = require("express");
const certPath = pathLib.join(__dirname, "..", "tmp", "localhost.pem");
const keyPath = pathLib.join(__dirname, "..", "tmp", "localhost-key.pem");
async function fileExists(path) {
try {
await fs.stat(path);
} catch (error) {
if (error.code === "ENOENT") {
return false;
}
throw error;
}
return true;
}
async function ensureCertsExist() {
if (!(await fileExists(certPath)) || !(await fileExists(keyPath))) {
console.log(
"Using mkcert to create localhost.pem and localhost-key.pem in " +
"the Rails tmp dir, to serve over HTTPS.",
);
const mkcertProc = spawn("mkcert", [
"-cert-file",
certPath,
"-key-file",
keyPath,
"localhost",
], {stdio: ["ignore", process.stdout, process.stderr]});
// Wait for the process to finish, raising an error if it fails.
await new Promise((resolve, reject) => {
mkcertProc.on("close", (code) => {
if (code === 0) {
resolve();
} else {
reject(new Error(`mkcert returned status ${code}`));
}
});
mkcertProc.on("error", (error) => {
reject(error);
});
});
}
}
async function startServer(port) {
const server = new OAuth2Server(
keyPath,
certPath,
);
await server.issuer.keys.add({
// A key we generated for the NeoPass test server. It's okay for its
// "secret" info to be here, because it's for development only!
kid: "neopass-server-DEVLOPMENT-ONLY-NOT-FOR-PRODUCTION",
p: "50btwsJlPbGLUFnCSBZzddyMX_oRQ8nz4lMrpAd4umPLqMUmS0NbBZNf6DI7s8PkRUxtV8KdvZh3OYWavFnbk55GDG4Y_J_wA4XlHU3d5KIfSNaIdbtVp4CFOq1lovho4sYX_26vcGgYb2Azeg7nz_gDpqNmIdJdKuZxzsrboK8",
kty: "RSA",
q: "xha0i9_lbOMQhmmni02Dtpocil26GI7W8xbOFyOvceBCRNf-XOA_-W_Xk9ItJRHnAWM1TML36PN0l864d4QAXbBo64FHu2cjdFKnXJNliJaPcOPAMQB_D8GSylU1gTwSpP_vVe8t232LeF1oBwbOoBIS-6NsOpLmL8Sezv6Fpac",
d: "WSUNeEd_EyaELK7wqT6GJJK_RfYjaE5h6USe9rD9cd_tQE2PaZWXMyZ4OCk5Z5hdG2ryZY7NYsOI2CPs8HCFBqMoKd0z0A0EgB8Dq2fe_-t5Rm0Zq1ZnI5tnBcZeQmw0hDT98Wg00FA53SSUqfnOgI_VuLvquM6f18_XQOKRRfTcwh1a4teDAH0g0s8FVOS5DANtg71mTdq5fEkWmQMD3qKC6SNrx3WXXHezDs0MWdeFqn9Dg7gssSqB7PnqB-hlC_fHnu4gm9nDqPTMzsJC2i8d3adm0AeORRCulGLe7hU-_TgTbZzgIYCgOK_asaewW-6Qk9qFj-J4djBaKIee-Q",
e: "AQAB",
use: "sig",
qi: "WNiwCcAk2x7e0KvuupL2DNU-JUjLEF9Onee5T9u9ihbgGSDIyP04_96TzCIK3wsY6lct64oOo0Er-z5cf_5eOBPD3n0eEL-JuKIgn0mEKrazJOnGQzlyeZPzk4dUO2J7D42ObopfYsoBIcJx-Y_43a6WORDMGSVCiURmKavTHUU",
dp: "p1_wj-Npq3VDElpzPQJqeuCrAoaSWhHcm21_hs0VdSbl6_UJ2qwbQnS-kudPx7A8El7WPw4MZHrjxdBIBImvXCzOGw7OrHz_ET2ka0nADUe7BlakGTgDLB7ZzHZSuNe36G5eTbCH7PyYunnPp0UERMEDu2RDdLSuUm7F7FdpDOc",
alg: "RS256",
dq: "purLCHKKKM7NRfYRsFiI_H2wPwfroHX8uqokz2rKk_Kc5NX9CNYOEmokBfO9BtenCIxIhX5k2G8NeD5BQrSAenIEdy5g-5FVVtevH1s023vDMyU29hOs_eHnh4d1poiwTUk8q_T3d1S7CZnr5r_drRSN2m1C7biLLwVHrLTceVE",
n: "svVfGU4NGcfBCmQiIOW5uzg5SAN2CWSIQSstnhqZoCdjy5OoKpKVR8O9TbDvxixrvkFyAav90Q0Xse8iFTcjfCKuqINYiuYMXhCvfBlc_DVVOQca9pMpN03LaDofd5Ll4_BFTtt1nSPahwWU7xDM-Bkkh_TcS2qS4N2xbpEGi0q0ZkrJN4WyiDBC2k9WbK-YHr4Rj4JKypFVSeBIrjxVPmlPzgfqlLGGIB0l92SnJDXDMlkWcCCTyLgqSBM04nkxGDSykq_ei76qCdRd7b10wMBaoS9DeBThAyHpur2LoPdH3gxbcwoWExi-jPlNP1LdKVZD8b95OY3CRyMAAMGdKQ",
});
await server.start(port, "localhost");
console.log(`Started NeoPass development server at: ${server.issuer.url}`);
}
async function main() {
await ensureCertsExist();
await startServer(8585);
}
main().catch((error) => {
console.error(error);
});