Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 0 additions & 23 deletions docs/runner/msal-apim-authentication.md

This file was deleted.

81 changes: 0 additions & 81 deletions docs/runner/secure-form-submissions.md

This file was deleted.

13 changes: 0 additions & 13 deletions model/src/data-model/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,18 +206,6 @@ export type Analytics = {
matomoUrl: string;
};

export interface MsalAuthorizerConfig {
tenantId: string;
clientId: string;
clientSecret: string;
scopes: string[];
}

export interface SecureFormSubmissionConfig extends MsalAuthorizerConfig {
/* Empty for now */
useAwsWafUserAgentWorkaround?: boolean;
}

/**
* `FormDefinition` is a typescript representation of `Schema`
*/
Expand Down Expand Up @@ -255,5 +243,4 @@ export type FormDefinition = {
confirmationSessionTimeout: number | undefined;
returnTo?: boolean | undefined;
documentUploadApiUrl?: string | undefined;
secureFormSubmissionConfig: SecureFormSubmissionConfig;
};
14 changes: 0 additions & 14 deletions model/src/schema/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,19 +322,6 @@ const exitSchema = joi.object().keys({
format: joi.string().allow("STATE", "WEBHOOK"),
});

const msalAuthorizeConfigSchema = joi.object().keys({
tenantId: joi.string().required(),
clientId: joi.string().required(),
clientSecret: joi.string().required(),
scopes: joi.array().items(joi.string()).min(1).required(),
});

const secureFormSubmissionConfig = msalAuthorizeConfigSchema.concat(
joi.object().keys({
useAwsWafUserAgentWorkaround: joi.bool().optional(),
})
);

export const Schema = joi
.object()
.required()
Expand Down Expand Up @@ -379,7 +366,6 @@ export const Schema = joi
confirmationSessionTimeout: joi.number().optional(),
returnTo: joi.boolean().optional(),
documentUploadApiUrl: joi.string().optional(),
secureFormSubmissionConfig: secureFormSubmissionConfig.optional(),
});

/**
Expand Down
1 change: 0 additions & 1 deletion runner/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
},
"license": "SEE LICENSE IN LICENSE",
"dependencies": {
"@azure/msal-node": "^5.2.1",
"@babel/runtime": "^7.23.3",
"@hapi/bell": "^13.0.1",
"@hapi/boom": "^10.0.1",
Expand Down
22 changes: 0 additions & 22 deletions runner/src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ import {
WebhookService,
ExitService,
FormSecurityService,
SecureFormSubmissionService,
getSecureFormSubmissionServiceInstance,
} from "./services";
import { HapiRequest, HapiResponseToolkit, RouteConfig } from "./types";
import getRequestInfo from "./utils/getRequestInfo";
Expand Down Expand Up @@ -179,26 +177,6 @@ async function createServer(routeConfig: RouteConfig) {
return h.continue;
});

const enginePlugin = configureEnginePlugin(
formFileName,
formFilePath,
options
);

for (const form of enginePlugin.options.configs) {
const formId = form.id;

if (form.configuration.secureFormSubmissionConfig) {
const instanceName = getSecureFormSubmissionServiceInstance(formId);
const namedService = new SecureFormSubmissionService(
form.configuration.secureFormSubmissionConfig
);
await server.registerService(
Schmervice.withName(instanceName, namedService)
);
}
}

await server.register(pluginLocale);
await server.register(pluginViews);
await server.register(
Expand Down
23 changes: 17 additions & 6 deletions runner/src/server/plugins/engine/configureEnginePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,29 @@ import {
} from "./services/configurationService";
import { idFromFilename } from "./helpers";
import config from "../../config";
import { FormDefinition } from "@xgovformbuilder/model";

type ConfigureEnginePlugin = (
formFileName?: string,
formFilePath?: string,
options?: EngineOptions
) => {
plugin: any;
options: {
modelOptions: {
relativeTo: string;
previewMode: boolean | undefined;
};
configs: FormConfiguration[];
previewMode: boolean | undefined;
};
};

const relativeTo = __dirname;

type EngineOptions = {
previewMode?: boolean;
};
export const configureEnginePlugin = (
export const configureEnginePlugin: ConfigureEnginePlugin = (
formFileName,
formFilePath,
options?: EngineOptions
Expand All @@ -25,10 +39,7 @@ export const configureEnginePlugin = (
if (formFileName && formFilePath) {
configs = [
{
configuration: require(path.join(
formFilePath,
formFileName
)) as FormDefinition,
configuration: require(path.join(formFilePath, formFileName)),
id: idFromFilename(formFileName),
},
];
Expand Down
73 changes: 19 additions & 54 deletions runner/src/server/services/formSecurityService.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import { HapiRequest, HapiServer } from "../types";

import { createHmacRaw } from "../utils/hmac";
import {
getSecureFormSubmissionServiceInstance,
SecureFormSubmissionService,
} from "./secureFormSubmissionService";

export class FormSecurityService {
/**
* Service responsible for securing form submissions. This service has been registered by {@link #createServer}
Expand All @@ -29,54 +23,25 @@ export class FormSecurityService {

let customSecurityHeaders: Record<string, string> = {};

if (form.def.webhookHmacSharedKey) {
/**
* If the config contains the OPTIONAL webhookHmacSharedKey, then we send HMAC Auth headers
* This is used to confirm ONLY X-Gov's backend is sending data to our API
* Everyone else will be Rejected
* (Used by KLS)
*/
const hmacKey = form.def.webhookHmacSharedKey;

const [hmacSignature, requestTime, hmacExpiryTime] = await createHmacRaw(
request.yar.id,
hmacKey
);
customSecurityHeaders = {
"X-Request-ID": request.yar.id.toString(),
"X-HMAC-Signature": hmacSignature.toString(),
"X-HMAC-Time": requestTime.toString(),
};
} else if (form.def.secureFormSubmissionConfig) {
/** Secure form submissions facilitated through a form specific instance of the secureFormSubmissionService
* We resolve the named service instance for the form
* If it exists, it's implementation will return a headers object \{ Authorization: "Bearer <Token>"\}
* For more information @see secure-form-submissions.md
*/

const instanceName = getSecureFormSubmissionServiceInstance(formId);
if (instanceName) {
const serviceInstance = request.services([])[
instanceName
] as SecureFormSubmissionService;

if (serviceInstance) {
const headers = await serviceInstance.getAuthHeader();
if (headers) {
const {
useAwsWafUserAgentWorkaround,
} = form.def.secureFormSubmissionConfig;

if (useAwsWafUserAgentWorkaround == true) {
/* AWS WAF forces User-Agent as part of auth, provide one to prevent 403 */
headers["User-Agent"] = "X-GOV Forms/v1.0";
}

customSecurityHeaders = headers;
}
}
}
}
/* Insert your custom security headers logic here
*
* You can access the form definition and options via the `form` variable, which is an instance of {@link FormModel}
*
* The operation is async to allow for any necessary asynchronous authentication operations, such as fetching additional data from a database or an external API or authenticating with an external service.
*
*
* For example you could set a custom Authorization header based on the forms name:
* if (form.name === "my-secure-form") {
* customSecurityHeaders["Authorization"] = "Bearer my-secure-token";
* }
*
*
* Or you could extend the form definition and fetch additional data from an external API and set a custom header based on the response:
* if (form.def.useMyCustomApiAuth) {
* const apiToken = await fetchTokenFromExternalService();
* customSecurityHeaders["Api-Token"] = apiToken;
* }
*/

return customSecurityHeaders;
}
Expand Down
5 changes: 0 additions & 5 deletions runner/src/server/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,3 @@ export { StatusService } from "./statusService";
export { AddressService } from "./addressService";
export { ExitService } from "./ExitService";
export { FormSecurityService } from "./formSecurityService";
export { MsalAuthorizer } from "./msalAuthorizerService";
export {
SecureFormSubmissionService,
getSecureFormSubmissionServiceInstance,
} from "./secureFormSubmissionService";
26 changes: 0 additions & 26 deletions runner/src/server/services/msalAuthorizerService.ts

This file was deleted.

27 changes: 0 additions & 27 deletions runner/src/server/services/secureFormSubmissionService.ts

This file was deleted.

Loading