Skip to content

Commit

Permalink
WIP, broken commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Carminepo2 committed Sep 24, 2024
1 parent 6c445ed commit 6917d52
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 77 deletions.
3 changes: 1 addition & 2 deletions packages/client-assertion-validation/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,9 @@ export type ApiKey = z.infer<typeof ApiKey>;

export type ValidationResult<T> = SuccessfulValidation<T> | FailedValidation;

export type SuccessfulValidation<T> = { errors: undefined; data: T };
export type SuccessfulValidation<T> = { data: T };
export type FailedValidation = {
errors: Array<ApiError<ErrorCodes>>;
data: undefined;
};

export const ClientAssertionValidationRequest = z.object({
Expand Down
20 changes: 4 additions & 16 deletions packages/client-assertion-validation/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,22 +194,10 @@ export const successfulValidation = <T>(
result: T
): SuccessfulValidation<T> => ({
data: result,
errors: undefined,
});

export const failedValidation = (
// errors: [[error1, error2, undefined], error3, undefined]
errors: Array<
Array<ApiError<ErrorCodes> | undefined> | ApiError<ErrorCodes> | undefined
>
): FailedValidation => {
const nestedArrayWithoutUndefined = errors.filter((a) => a !== undefined);
const flattenedArray = nestedArrayWithoutUndefined.flat(1);
const flattenedArrayWithoutUndefined = flattenedArray.filter(
(e) => e !== undefined
);
return {
data: undefined,
errors: flattenedArrayWithoutUndefined as Array<ApiError<ErrorCodes>>,
};
};
errors: Array<ApiError<ErrorCodes> | undefined>
): FailedValidation => ({
errors: errors.filter((v): v is NonNullable<typeof v> => Boolean(v)),
});
171 changes: 112 additions & 59 deletions packages/client-assertion-validation/src/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,34 @@ export const validateRequestParameters = (
return failedValidation([assertionTypeError, grantTypeError]);
};

type ValidationOutput = {
jti: ValidationResult<string>;
iat: ValidationResult<number>;
};

function isValidationSuccess(
validationResult: ValidationResult<unknown>
): validationResult is Extract<typeof validationResult, { data: unknown }> {
return "data" in validationResult && Boolean(validationResult.data);
}

function isValidationError(
validationResult: ValidationResult<unknown>
): validationResult is Extract<typeof validationResult, { errors: unknown }> {
return "errors" in validationResult && Array.isArray(validationResult.errors);
}

function isAllValidationSuccess(
validationOutput: ValidationOutput
): validationOutput is {
[TKey in keyof typeof validationOutput]: Extract<
(typeof validationOutput)[TKey],
{ data: unknown }
>;
} {
return Object.values(validationOutput).every(isValidationSuccess);
}

// eslint-disable-next-line complexity
export const verifyClientAssertion = (
clientAssertionJws: string,
Expand All @@ -121,48 +149,14 @@ export const verifyClientAssertion = (
return failedValidation([unexpectedClientAssertionPayload()]);
}

const { errors: jtiErrors, data: validatedJti } = validateJti(
decoded.payload.jti
);
const { errors: iatErrors, data: validatedIat } = validateIat(
decoded.payload.iat
);
const { errors: expErrors, data: validatedExp } = validateExp(
decoded.payload.exp
);
const { errors: issErrors, data: validatedIss } = validateIss(
decoded.payload.iss
);
const { errors: subErrors, data: validatedSub } = validateSub(
decoded.payload.sub,
clientId
);
const { errors: purposeIdErrors, data: validatedPurposeId } =
validatePurposeId(decoded.payload.purposeId);
const { errors: kidErrors, data: validatedKid } = validateKid(
decoded.header.kid
);
const { errors: audErrors, data: validatedAud } = validateAudience(
decoded.payload.aud
);
const { errors: algErrors, data: validatedAlg } = validateAlgorithm(
decoded.header.alg
);
const { errors: digestErrors, data: validatedDigest } = validateDigest(
decoded.payload.digest
);
if (
!jtiErrors &&
!iatErrors &&
!expErrors &&
!issErrors &&
!subErrors &&
!purposeIdErrors &&
!kidErrors &&
!audErrors &&
!algErrors &&
!digestErrors
) {
const validationOutput: ValidationOutput = {
jti: validateJti(decoded.payload.jti),
iat: validateIat(decoded.payload.iat),
};

if (isAllValidationSuccess(validationOutput)) {
// build client assertion

const result: ClientAssertion = {
header: {
kid: validatedKid,
Expand All @@ -171,8 +165,8 @@ export const verifyClientAssertion = (
payload: {
sub: validatedSub,
purposeId: validatedPurposeId,
jti: validatedJti,
iat: validatedIat,
jti: validationOutput.jti.data,
iat: validationOutput.iat.data,
iss: validatedIss,
aud: validatedAud,
exp: validatedExp,
Expand All @@ -181,18 +175,11 @@ export const verifyClientAssertion = (
};
return successfulValidation(result);
}
return failedValidation([
jtiErrors,
iatErrors,
expErrors,
issErrors,
subErrors,
purposeIdErrors,
kidErrors,
audErrors,
algErrors,
digestErrors,
]);

const errors = Object.values(validationOutput)
.filter(isValidationError)
.flatMap(({ errors }) => errors);
return failedValidation(errors);
} catch (error) {
return failedValidation([unexpectedClientAssertionPayload()]);
}
Expand Down Expand Up @@ -240,9 +227,14 @@ export const validateClientKindAndPlatformState = (
)
.with(clientKindTokenStates.consumer, () => {
if (ConsumerKey.safeParse(key).success) {
const { errors: platformStateErrors } = validatePlatformState(
key as ConsumerKey
);
const validationResult = validatePlatformState(key as ConsumerKey);

if (isValidationSuccess(validationResult)) {
// ...
} else {
validationResult.errors;

Check failure on line 235 in packages/client-assertion-validation/src/validation.ts

View workflow job for this annotation

GitHub Actions / Lint

Expected an assignment or function call and instead saw an expression
}

const purposeIdError = jwt.payload.purposeId
? undefined
: purposeIdNotProvided();
Expand All @@ -257,3 +249,64 @@ export const validateClientKindAndPlatformState = (
]);
})
.exhaustive();

// const { errors: jtiErrors, data: validatedJti } = validateJti(
// decoded.payload.jti
// );
// const { errors: iatErrors, data: validatedIat } = validateIat(
// decoded.payload.iat
// );
// const { errors: expErrors, data: validatedExp } = validateExp(
// decoded.payload.exp
// );
// const { errors: issErrors, data: validatedIss } = validateIss(
// decoded.payload.iss
// );
// const { errors: subErrors, data: validatedSub } = validateSub(
// decoded.payload.sub,
// clientId
// );
// const { errors: purposeIdErrors, data: validatedPurposeId } =
// validatePurposeId(decoded.payload.purposeId);
// const { errors: kidErrors, data: validatedKid } = validateKid(
// decoded.header.kid
// );
// const { errors: audErrors, data: validatedAud } = validateAudience(
// decoded.payload.aud
// );
// const { errors: algErrors, data: validatedAlg } = validateAlgorithm(
// decoded.header.alg
// );
// const { errors: digestErrors, data: validatedDigest } = validateDigest(
// decoded.payload.digest
// );
// if (
// !jtiErrors &&
// !iatErrors &&
// !expErrors &&
// !issErrors &&
// !subErrors &&
// !purposeIdErrors &&
// !kidErrors &&
// !audErrors &&
// !algErrors &&
// !digestErrors
// ) {
// const result: ClientAssertion = {
// header: {
// kid: validatedKid,
// alg: validatedAlg,
// },
// payload: {
// sub: validatedSub,
// purposeId: validatedPurposeId,
// jti: validatedJti,
// iat: validatedIat,
// iss: validatedIss,
// aud: validatedAud,
// exp: validatedExp,
// digest: validatedDigest,
// },
// };
// return successfulValidation(result);
// }

0 comments on commit 6917d52

Please sign in to comment.