@hellocoop/api
Version:
Client API for Hellō https://hello.dev
102 lines (101 loc) • 3.79 kB
JavaScript
// process OP Commands
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const config_1 = __importDefault(require("../lib//config"));
const packageMetadata_1 = require("../lib/packageMetadata");
const issuers = {
'http://mockin:3333': {
issuer: 'http://mockin:3333',
introspection_endpoint: 'http://mockin:3333/oauth/introspect',
},
'http://127.0.0.1:3333': {
issuer: 'http://127.0.0.1:3333',
introspection_endpoint: 'http://127.0.0.1:3333/oauth/introspect',
},
'https://issuer.hello.coop': {
issuer: 'https://issuer.hello.coop',
introspection_endpoint: 'https://wallet.hello.coop/oauth/introspect',
}
};
const verifyCommandToken = async (command_token) => {
const [encodedHeader, encodedPayload, signature] = command_token.split('.');
if (!encodedHeader || !encodedPayload || !signature) {
return false;
}
try {
const payload = JSON.parse(Buffer.from(encodedPayload, 'base64url').toString());
const iss = payload?.iss;
if (!iss) {
console.error('commands.verifyCommandToken: missing issuer', payload);
return false;
}
if (!issuers[iss]) {
console.error('commands.verifyCommandToken: unknown issuer', iss);
return false;
}
const introspection_endpoint = issuers[iss].introspection_endpoint;
const data = new URLSearchParams();
data.append('token', command_token);
data.append('client_id', config_1.default.clientId || 'test-app');
const response = await fetch(introspection_endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: data.toString()
});
if (!response.ok) {
console.error('commands.verifyCommandToken: introspection failed', response.status);
return false;
}
const json = await response.json();
return json;
}
catch (e) {
console.error('error verifying command token', e);
return false;
}
};
const handleMetadata = async (res, claims) => {
const { iss, tenant } = claims;
const { name, version } = packageMetadata_1.PackageMetadata.getMetadata();
const metadataResponse = {
context: {
package_name: name,
package_version: version,
iss,
},
commands_uri: config_1.default.redirectURI || 'unknown', // might not be set
commands_supported: ['metadata'],
commands_ttl: 0,
client_id: config_1.default.clientId || 'unknown'
};
if (tenant)
metadataResponse.context.tenant = tenant;
return res.json(metadataResponse);
};
const handleCommand = async (req, res, params) => {
const { command_token } = params;
if (!command_token) {
// should not happen
return res.status(500);
}
var claims = await verifyCommandToken(command_token);
if (!claims) {
res.status(400);
console.error('invalid command token', command_token);
return res.json({ error: 'invalid_request', error_description: 'invalid command token' });
}
const { command } = claims;
const commandsConfigured = config_1.default.commandHandler;
if (!commandsConfigured && (command === 'metadata')) {
return handleMetadata(res, claims);
}
if (config_1.default.commandHandler) {
return config_1.default.commandHandler(res, claims);
}
res.status(400);
return res.json({ error: 'unsupported_command' });
};
exports.default = handleCommand;
;