Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
improve validator logic
  • Loading branch information
xil222 committed Apr 15, 2021
commit e565db3bd328ed2348e0b414f8c20bcbe8923aec
77 changes: 35 additions & 42 deletions src/auth/auth-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -800,59 +800,52 @@ export class OIDCConfig implements OIDCAuthProviderConfig {
);
}
if (validator.isNonNullObject(options.responseType) && typeof options.responseType !== 'undefined') {
let idTokenType;
let codeType;
let setIdTokenType = false;
let setCodeType = false;
for (const responseTypeKey in options.responseType) {
if (!(responseTypeKey in validResponseTypes)) {
Object.keys(options.responseType).forEach((key) => {
if (!(key in validResponseTypes)) {
throw new FirebaseAuthError(
AuthClientErrorCode.INVALID_CONFIG,
`"${responseTypeKey}" is not a valid OAuthResponseType parameter.`,
`"${key}" is not a valid OAuthResponseType parameter.`,
);
}
});

const idToken = options.responseType.idToken;
if (typeof idToken !== 'undefined') {
if (!validator.isBoolean(idToken)) {
throw new FirebaseAuthError(
AuthClientErrorCode.INVALID_ARGUMENT,
'"OIDCAuthProviderConfig.responseType.idToken" must be a boolean.',
);
} else {
if (responseTypeKey === 'idToken') {
if (!validator.isBoolean(options.responseType.idToken)) {
throw new FirebaseAuthError(
AuthClientErrorCode.INVALID_ARGUMENT,
'"OIDCAuthProviderConfig.responseType.idToken" must be a boolean.',
);
}
if (typeof options.responseType.idToken !== 'undefined') {
idTokenType = options.responseType.idToken;
setIdTokenType = true;
}
} else if (responseTypeKey === 'code') {
if (!validator.isBoolean(options.responseType.code)) {
throw new FirebaseAuthError(
AuthClientErrorCode.INVALID_ARGUMENT,
'"OIDCAuthProviderConfig.responseType.code" must be a boolean.',
);
}
if (typeof options.responseType.code !== 'undefined') {
codeType = options.responseType.code;
setCodeType = true;
}
}
}
}


const code = options.responseType.code;
if (typeof code !== 'undefined') {
if (!validator.isBoolean(code)) {
throw new FirebaseAuthError(
AuthClientErrorCode.INVALID_ARGUMENT,
'"OIDCAuthProviderConfig.responseType.code" must be a boolean.',
);
}

// If code flow is enabled, client secret must be provided.
if (typeof options.clientSecret === 'undefined') {
throw new FirebaseAuthError(
AuthClientErrorCode.MISSING_OAUTH_CLIENT_SECRET,
'The OAuth configuration client secret is required to enable OIDC code flow.',
);
}
}

const allKeys = Object.keys(options.responseType).length;
const enabledCount = Object.values(options.responseType).filter(Boolean).length;
// Only one of OAuth response types can be set to true.
if ((setIdTokenType && setCodeType) &&
((idTokenType && codeType) ||
(!idTokenType && !codeType))) {
if (allKeys > 1 && enabledCount != 1) {
throw new FirebaseAuthError(
AuthClientErrorCode.INVALID_OAUTH_RESPONSETYPE,
'Only exactly one OAuth responseType should be set to true.',
);
}
// If code flow is enabled, client secret must be provided.
if (codeType && typeof options.clientSecret === 'undefined') {
throw new FirebaseAuthError(
AuthClientErrorCode.MISSING_OAUTH_CLIENT_SECRET,
'The OAuth configuration client secret is required to enable OIDC code flow.',
);
}
}
}

Expand Down
3 changes: 1 addition & 2 deletions test/unit/auth/auth-config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -958,8 +958,7 @@ describe('OIDCConfig', () => {

it('should not throw when only idToken responseType is set to true', () => {
const validRequest = deepCopy(clientRequest) as any;
const validResponseType = { idToken: true };
validRequest.responseType = validResponseType;
validRequest.responseType = { idToken: true };
expect(() => OIDCConfig.validate(validRequest, true)).not.to.throw();
});

Expand Down