Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Remove detailed error from error messages #9267

Open
wants to merge 6 commits into
base: alpha
Choose a base branch
from
Open
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
1 change: 0 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/Adapters/Auth/OAuth1Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ var Parse = require('parse/node').Parse;

var OAuth = function (options) {
if (!options) {
throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'No options passed to OAuth');
console.error('No options passed to OAuth');
throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Configuration error.');
}
this.consumer_key = options.consumer_key;
this.consumer_secret = options.consumer_secret;
Expand Down
16 changes: 10 additions & 6 deletions src/Adapters/Auth/apple.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,19 @@ const getAppleKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => {
try {
key = await authUtils.getSigningKey(client, keyId);
} catch (error) {
console.error(`Unable to find matching key for Key ID: ${keyId}. Error: ${error.message}`);
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
`Unable to find matching key for Key ID: ${keyId}`
`Unauthorized`
);
}
return key;
};

const verifyIdToken = async ({ token, id }, { clientId, cacheMaxEntries, cacheMaxAge }) => {
if (!token) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`);
console.error('Invalid token');
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Unauthorized`);
}

const { kid: keyId, alg: algorithm } = authUtils.getHeaderFromToken(token);
Expand All @@ -51,19 +53,21 @@ const verifyIdToken = async ({ token, id }, { clientId, cacheMaxEntries, cacheMa
});
} catch (exception) {
const message = exception.message;

throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `${message}`);
console.error(`JWT verification failed. Error: ${message}`);
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Unauthorized`);
}

if (jwtClaims.iss !== TOKEN_ISSUER) {
console.error(`Token issuer mismatch. Expected: ${TOKEN_ISSUER}, Received: ${jwtClaims.iss}`);
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
`id token not issued by correct OpenID provider - expected: ${TOKEN_ISSUER} | from: ${jwtClaims.iss}`
`Unauthorized`
);
}

if (jwtClaims.sub !== id) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `auth data is invalid for this user.`);
console.error(`Token subject mismatch for user ID: ${id}.`);
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Unauthorized`);
}
return jwtClaims;
};
Expand Down
26 changes: 17 additions & 9 deletions src/Adapters/Auth/facebook.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ function validateGraphToken(authData, options) {
if ((data && data.id == authData.id) || (process.env.TESTING && authData.id === 'test')) {
return;
}
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is invalid for this user.');
console.error(`Invalid Facebook auth for user with ID: ${authData.id}`);
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Unauthorized');
});
}

Expand All @@ -38,16 +39,19 @@ async function validateGraphAppId(appIds, authData, options) {
return;
}
if (!Array.isArray(appIds)) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'appIds must be an array.');
console.error('appIds must be an array.');
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Unauthorized');
}
if (!appIds.length) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is not configured.');
console.error('Authentication is not configured.')
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Unauthorized');
}
const data = await graphRequest(
`app?access_token=${access_token}${getAppSecretPath(authData, options)}`
);
if (!data || !appIds.includes(data.id)) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is invalid for this user.');
console.error('Invalid authentication data.')
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Unauthorized');
}
}

Expand All @@ -63,17 +67,18 @@ const getFacebookKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => {
try {
key = await authUtils.getSigningKey(client, keyId);
} catch (error) {
console.error(`Unable to find matching key for Key ID: ${keyId}. Error: ${error.message}`);
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
`Unable to find matching key for Key ID: ${keyId}`
`Unable to validate authentication key.`
);
}
return key;
};

const verifyIdToken = async ({ token, id }, { clientId, cacheMaxEntries, cacheMaxAge }) => {
if (!token) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'id token is invalid for this user.');
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'invalid token.');
}

const { kid: keyId, alg: algorithm } = authUtils.getHeaderFromToken(token);
Expand All @@ -94,19 +99,22 @@ const verifyIdToken = async ({ token, id }, { clientId, cacheMaxEntries, cacheMa
});
} catch (exception) {
const message = exception.message;
console.error(`JWT verification failed. Error: ${message}`);

throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `${message}`);
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Unauthorized access.`);
}

if (jwtClaims.iss !== TOKEN_ISSUER) {
console.error(`id token not issued by correct OpenID provider - expected: ${TOKEN_ISSUER} | from: ${jwtClaims.iss}`);
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
`id token not issued by correct OpenID provider - expected: ${TOKEN_ISSUER} | from: ${jwtClaims.iss}`
`Unauthorized access.`
);
}

if (jwtClaims.sub !== id) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'auth data is invalid for this user.');
console.error(`Token subject mismatch for user ID: ${id}.`);
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid authentication data.');
}
return jwtClaims;
};
Expand Down
24 changes: 16 additions & 8 deletions src/Adapters/Auth/gcenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ function convertX509CertToPEM(X509Cert) {

async function getAppleCertificate(publicKeyUrl) {
if (!verifyPublicKeyUrl(publicKeyUrl)) {
console.error(`Invalid publicKeyUrl: ${publicKeyUrl}`);
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
`Apple Game Center - invalid publicKeyUrl: ${publicKeyUrl}`
`Unauthorized`
);
}
if (cache[publicKeyUrl]) {
Expand All @@ -62,9 +63,10 @@ async function getAppleCertificate(publicKeyUrl) {
cert_headers['content-length'] == null ||
cert_headers['content-length'] > 10000
) {
console.error(`Invalid publicKeyUrl: ${publicKeyUrl}`);
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
`Apple Game Center - invalid publicKeyUrl: ${publicKeyUrl}`
`Unauthorized`
);
}
const { certificate, headers } = await getCertificate(publicKeyUrl);
Expand Down Expand Up @@ -126,29 +128,33 @@ function verifySignature(publicKey, authData) {
verifier.update(authData.salt, 'base64');

if (!verifier.verify(publicKey, authData.signature, 'base64')) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Apple Game Center - invalid signature');
console.error('Invalid signature during Apple Game Center verification.');
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Unauthorized');
}
}

function verifyPublicKeyIssuer(cert, publicKeyUrl) {
const publicKeyCert = pki.certificateFromPem(cert);
if (!ca.cert) {
console.error('Invalid root certificate during Apple Game Center verification.');
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
'Apple Game Center auth adapter parameter `rootCertificateURL` is invalid.'
'Unauthorized'
);
}
try {
if (!ca.cert.verify(publicKeyCert)) {
console.error(`Invalid publicKeyUrl issuer: ${publicKeyUrl}`);
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
`Apple Game Center - invalid publicKeyUrl: ${publicKeyUrl}`
`Unauthorized`
);
}
} catch (e) {
console.error(`Error verifying publicKeyUrl issuer: ${e.message}`);
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
`Apple Game Center - invalid publicKeyUrl: ${publicKeyUrl}`
`Unauthorized`
);
}
return cert;
Expand All @@ -157,7 +163,8 @@ function verifyPublicKeyIssuer(cert, publicKeyUrl) {
// Returns a promise that fulfills if this user id is valid.
async function validateAuthData(authData) {
if (!authData.id) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Apple Game Center - authData id missing');
console.error('Missing authData id during Apple Game Center validation.');
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Unauthorized');
}
authData.playerId = authData.id;
const publicKey = await getAppleCertificate(authData.publicKeyUrl);
Expand All @@ -179,9 +186,10 @@ async function validateAppId(appIds, authData, options = {}) {
headers['content-length'] == null ||
headers['content-length'] > 10000
) {
console.error('Invalid root certificate URL during Apple Game Center validation.');
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
'Apple Game Center auth adapter parameter `rootCertificateURL` is invalid.'
'Unauthorized'
);
}
ca.cert = pki.certificateFromPem(certificate);
Expand Down
3 changes: 2 additions & 1 deletion src/Adapters/Auth/github.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ function validateAuthData(authData) {
if (data && data.id == authData.id) {
return;
}
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Github auth is invalid for this user.');
console.error('Github auth is invalid for this user.');
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Unauthorized');
});
}

Expand Down
10 changes: 7 additions & 3 deletions src/Adapters/Auth/google.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,22 @@ async function verifyIdToken({ id_token: token, id }, { clientId }) {
});
} catch (exception) {
const message = exception.message;
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `${message}`);
console.error(`Google Sign-In Validation Error: ${message}`);
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Unauthorized`);
}

if (jwtClaims.iss !== TOKEN_ISSUER && jwtClaims.iss !== HTTPS_TOKEN_ISSUER) {
console.error(`id token not issued by correct provider - expected: ${TOKEN_ISSUER} or ${HTTPS_TOKEN_ISSUER} | from: ${jwtClaims.iss}`);
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
`id token not issued by correct provider - expected: ${TOKEN_ISSUER} or ${HTTPS_TOKEN_ISSUER} | from: ${jwtClaims.iss}`
'Unauthorized'
);
}

if (jwtClaims.sub !== id) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `auth data is invalid for this user.`);
const errMsg = `Token subject does not match user id.`;
console.error(`Google Sign-In Validation Error: ${errMsg}`);
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Unauthorized');
}

if (clientId && jwtClaims.aud !== clientId) {
Expand Down
3 changes: 2 additions & 1 deletion src/Adapters/Auth/gpgames.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ async function validateAuthData(authData) {
`https://www.googleapis.com/games/v1/players/${authData.id}?access_token=${authData.access_token}`
);
if (!(response && response.playerId === authData.id)) {
console.error('Google Play Games Services - authData is invalid for this user.');
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
'Google Play Games Services - authData is invalid for this user.'
'Authentication Failed'
);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/Adapters/Auth/instagram.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ function validateAuthData(authData) {
if (user && user.id == authData.id) {
return;
}
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Instagram auth is invalid for this user.');
console.error('Instagram auth is invalid for this user.')
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Unauthorized');
});
}

Expand Down
3 changes: 2 additions & 1 deletion src/Adapters/Auth/janraincapture.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ function validateAuthData(authData, options) {
if (data && data.stat == 'ok' && data.result == authData.id) {
return;
}
console.error('Janrain capture auth is invalid for this user.')
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
'Janrain capture auth is invalid for this user.'
'Unauthorized'
);
});
}
Expand Down
3 changes: 2 additions & 1 deletion src/Adapters/Auth/janrainengage.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ function validateAuthData(authData, options) {
if (data && data.stat == 'ok' && data.profile.identifier == authData.id) {
return;
}
console.error('Janrain engage auth is invalid for this user.');
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
'Janrain engage auth is invalid for this user.'
'Unauthorized'
);
});
}
Expand Down
16 changes: 11 additions & 5 deletions src/Adapters/Auth/keycloak.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,12 @@ const arraysEqual = (_arr1, _arr2) => {

const handleAuth = async ({ access_token, id, roles, groups } = {}, { config } = {}) => {
if (!(access_token && id)) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Missing access token and/or User id');
console.error('Missing access token and/or User id');
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Authentication failed');
}
if (!config || !(config['auth-server-url'] && config['realm'])) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Missing keycloak configuration');
console.error('Missing Keycloak configuration');
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Authentication failed');
}
try {
const response = await httpsRequest.get({
Expand All @@ -73,18 +75,22 @@ const handleAuth = async ({ access_token, id, roles, groups } = {}, { config } =
) {
return;
}
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid authentication');
console.error('Invalid authentication: response data does not match');
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Authentication failed');
} catch (e) {
if (e instanceof Parse.Error) {
console.error('Parse Error:', e.message);
throw e;
}
const error = JSON.parse(e.text);
if (error.error_description) {
throw new Parse.Error(Parse.Error.HOSTING_ERROR, error.error_description);
console.error('Authentication server error:', error.error_description);
throw new Parse.Error(Parse.Error.HOSTING_ERROR, 'Authentication failed');
} else {
console.error('Could not connect to the authentication server');
throw new Parse.Error(
Parse.Error.HOSTING_ERROR,
'Could not connect to the authentication server'
'Authentication failed'
);
}
}
Expand Down
Loading
Loading