"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
require("jest-extended");
const uuid_1 = require("uuid");
const jose_1 = require("jose");
const axios_1 = __importDefault(require("axios"));
const cactus_core_1 = require("@hyperledger/cactus-core");
const public_api_1 = require("../../../main/typescript/public-api");
const plugin_ledger_connector_stub_1 = require("../fixtures/plugin-ledger-connector-stub/plugin-ledger-connector-stub");
const run_transaction_endpoint_1 = require("../fixtures/plugin-ledger-connector-stub/web-services/run-transaction-endpoint");
const deploy_contract_endpoint_1 = require("../fixtures/plugin-ledger-connector-stub/web-services/deploy-contract-endpoint");
const unprotected_action_endpoint_1 = require("../fixtures/plugin-ledger-connector-stub/web-services/unprotected-action-endpoint");
const testCase = "API server enforces scope requirements on top of generic authz";
const logLevel = "TRACE";
describe(testCase, () => {
    let apiServer;
    afterAll(async () => {
        await apiServer.shutdown();
    });
    test(testCase, async () => {
        var _a, _b;
        const jwtKeyPair = await (0, jose_1.generateKeyPair)("RS256", {
            modulusLength: 4096,
        });
        const jwtPublicKey = await (0, jose_1.exportSPKI)(jwtKeyPair.publicKey);
        const expressJwtOptions = {
            algorithms: ["RS256"],
            secret: jwtPublicKey,
            audience: (0, uuid_1.v4)(),
            issuer: (0, uuid_1.v4)(),
        };
        expect(expressJwtOptions).toBeTruthy();
        const unprotectedActionEp = new unprotected_action_endpoint_1.UnprotectedActionEndpoint({
            connector: {},
            logLevel,
        });
        const authorizationConfig = {
            unprotectedEndpointExemptions: [unprotectedActionEp.getPath()],
            expressJwtOptions,
            socketIoJwtOptions: { secret: jwtPublicKey },
        };
        const pluginRegistry = new cactus_core_1.PluginRegistry();
        const plugin = new plugin_ledger_connector_stub_1.PluginLedgerConnectorStub({
            logLevel,
            pluginRegistry,
            instanceId: (0, uuid_1.v4)(),
        });
        pluginRegistry.add(plugin);
        const configService = new public_api_1.ConfigService();
        const apiSrvOpts = await configService.newExampleConfig();
        apiSrvOpts.authorizationProtocol = public_api_1.AuthorizationProtocol.JSON_WEB_TOKEN;
        apiSrvOpts.authorizationConfigJson = authorizationConfig;
        apiSrvOpts.configFile = "";
        apiSrvOpts.apiCorsDomainCsv = "*";
        apiSrvOpts.apiPort = 0;
        apiSrvOpts.cockpitPort = 0;
        apiSrvOpts.grpcPort = 0;
        apiSrvOpts.crpcPort = 0;
        apiSrvOpts.apiTlsEnabled = false;
        apiSrvOpts.plugins = [];
        const config = await configService.newExampleConfigConvict(apiSrvOpts);
        apiServer = new public_api_1.ApiServer({
            config: config.getProperties(),
            pluginRegistry,
        });
        const startResponse = apiServer.start();
        await expect(startResponse).not.toReject();
        expect(startResponse).toBeTruthy();
        const addressInfoApi = (await startResponse).addressInfoApi;
        const protocol = apiSrvOpts.apiTlsEnabled ? "https" : "http";
        const { address, port } = addressInfoApi;
        const apiHost = `${protocol}://${address}:${port}`;
        const jwtPayload = {
            name: "Peter",
            location: "London",
            scope: [...run_transaction_endpoint_1.RunTransactionEndpoint.OAUTH2_SCOPES],
        };
        const token = await new jose_1.SignJWT(jwtPayload)
            .setProtectedHeader({
            alg: "RS256",
        })
            .setIssuer(expressJwtOptions.issuer)
            .setAudience(expressJwtOptions.audience)
            .sign(jwtKeyPair.privateKey);
        const runTxEp = new run_transaction_endpoint_1.RunTransactionEndpoint({
            connector: {},
            logLevel,
        });
        const req1 = {
            requestId: (0, uuid_1.v4)(),
        };
        const res1 = await axios_1.default.request({
            data: req1,
            url: `${apiHost}${runTxEp.getPath()}`,
            method: runTxEp.getVerbLowerCase(),
            headers: {
                Authorization: `Bearer ${token}`,
            },
        });
        expect(res1).toBeTruthy();
        expect(res1.status).toEqual(200);
        expect(typeof res1.data).toBe("object");
        expect(typeof res1.data.data).toBeTruthy();
        expect(typeof res1.data.data.requestId).toBeTruthy();
        expect(res1.data.data.requestId).toBe(req1.requestId);
        try {
            const deployContractEp = new deploy_contract_endpoint_1.DeployContractEndpoint({
                connector: {},
                logLevel,
            });
            await axios_1.default.request({
                url: `${apiHost}${deployContractEp.getPath()}`,
                method: deployContractEp.getVerbLowerCase(),
                headers: {
                    Authorization: `Bearer ${token}`,
                },
            });
        }
        catch (out) {
            if (axios_1.default.isAxiosError(out)) {
                expect(out).toBeTruthy();
                expect(out.response).toBeTruthy();
                expect(out).toHaveProperty(["response", "status"], 403);
                expect((_a = out.response) === null || _a === void 0 ? void 0 : _a.data.data).toBeFalsy();
                expect((_b = out.response) === null || _b === void 0 ? void 0 : _b.data.success).toBeFalsy();
            }
            else {
                fail("expected an axios error, got something else");
            }
        }
    });
});
//# sourceMappingURL=data:application/json;base64, 