76 lines
2.3 KiB
TypeScript
76 lines
2.3 KiB
TypeScript
import { Collection } from "@discordjs/collection";
|
|
import {
|
|
CredentialField,
|
|
CredentialTypeField,
|
|
ValueType,
|
|
} from "./credentialTypeDefs";
|
|
import GenericError from "../../Errors/GenericError";
|
|
|
|
export interface ValidatedField {
|
|
fieldId: string;
|
|
value: string;
|
|
secure: boolean;
|
|
isMultiCredential?: boolean;
|
|
subCredentials?: string[];
|
|
}
|
|
|
|
/**
|
|
* Field Validator
|
|
*
|
|
* This method will take a record of the fields being submitted and compare them against a record of the acceptable fields
|
|
* for a credential type. If any of the submitted fields do not match an acceptable field, an error will be thrown.
|
|
*
|
|
* If all the credentials pass, it will return a processed version of the submitted fields including fields that need to be
|
|
* stored securely (encrypted) and fields that do not.
|
|
*
|
|
* Multi-credential fields are handled specially — they don't carry a direct value but instead
|
|
* reference sub-credential IDs.
|
|
*
|
|
* @param fields - The fields in object form that are being submitted.
|
|
* @param acceptableFields - The acceptable field to be compared against.
|
|
*/
|
|
export const fieldValidator = async (
|
|
fields: CredentialField[],
|
|
acceptableFields: CredentialTypeField[],
|
|
): Promise<ValidatedField[]> => {
|
|
const afCollection = new Collection(acceptableFields.map((f) => [f.id, f]));
|
|
|
|
await Promise.all(
|
|
fields.map(async (field) => {
|
|
const matchingField = afCollection.get(field.fieldId);
|
|
if (!matchingField) {
|
|
throw new GenericError({
|
|
message: `Invalid field ID: ${field.fieldId}`,
|
|
name: "InvalidCredentialField",
|
|
cause: `No acceptable field with ID '${field.fieldId}' found.`,
|
|
status: 400,
|
|
});
|
|
}
|
|
|
|
return;
|
|
}),
|
|
);
|
|
|
|
return fields.map((field) => {
|
|
const matchingField = afCollection.get(field.fieldId)!;
|
|
|
|
// Multi-credential fields don't carry a direct value;
|
|
// they reference sub-credential IDs instead.
|
|
if (matchingField.valueType === ValueType.MULTI_CREDENTIAL) {
|
|
return {
|
|
fieldId: field.fieldId,
|
|
value: "",
|
|
secure: false,
|
|
isMultiCredential: true,
|
|
subCredentials: field.subCredentials ?? [],
|
|
};
|
|
}
|
|
|
|
return {
|
|
fieldId: field.fieldId,
|
|
value: field.value,
|
|
secure: matchingField.secure,
|
|
};
|
|
});
|
|
};
|