mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 10:31:15 +00:00
feat(core): Make OAuth2 error handling consistent with success handling (#5555)
Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
This commit is contained in:
@@ -11,7 +11,6 @@ import type {
|
||||
WorkflowExecuteMode,
|
||||
INodeCredentialsDetails,
|
||||
ICredentialsEncrypted,
|
||||
IDataObject,
|
||||
} from 'n8n-workflow';
|
||||
import { LoggerProxy } from 'n8n-workflow';
|
||||
import { resolve as pathResolve } from 'path';
|
||||
@@ -112,7 +111,7 @@ oauth2CredentialController.get(
|
||||
);
|
||||
|
||||
const token = new Csrf();
|
||||
// Generate a CSRF prevention token and send it as a OAuth2 state stringma/ERR
|
||||
// Generate a CSRF prevention token and send it as an OAuth2 state string
|
||||
const csrfSecret = token.secretSync();
|
||||
const state = {
|
||||
token: token.create(csrfSecret),
|
||||
@@ -174,6 +173,9 @@ oauth2CredentialController.get(
|
||||
}),
|
||||
);
|
||||
|
||||
const renderCallbackError = (res: express.Response, errorMessage: string) =>
|
||||
res.render('oauth-error-callback', { error: { message: errorMessage } });
|
||||
|
||||
/**
|
||||
* GET /oauth2-credential/callback
|
||||
*
|
||||
@@ -188,12 +190,12 @@ oauth2CredentialController.get(
|
||||
const { code, state: stateEncoded } = req.query;
|
||||
|
||||
if (!code || !stateEncoded) {
|
||||
const errorResponse = new ResponseHelper.ServiceUnavailableError(
|
||||
return renderCallbackError(
|
||||
res,
|
||||
`Insufficient parameters for OAuth2 callback. Received following query parameters: ${JSON.stringify(
|
||||
req.query,
|
||||
)}`,
|
||||
);
|
||||
return ResponseHelper.sendErrorResponse(res, errorResponse);
|
||||
}
|
||||
|
||||
let state;
|
||||
@@ -203,31 +205,21 @@ oauth2CredentialController.get(
|
||||
token: string;
|
||||
};
|
||||
} catch (error) {
|
||||
const errorResponse = new ResponseHelper.ServiceUnavailableError(
|
||||
'Invalid state format returned',
|
||||
);
|
||||
return ResponseHelper.sendErrorResponse(res, errorResponse);
|
||||
return renderCallbackError(res, 'Invalid state format returned');
|
||||
}
|
||||
|
||||
const credential = await getCredentialWithoutUser(state.cid);
|
||||
|
||||
if (!credential) {
|
||||
LoggerProxy.error('OAuth2 callback failed because of insufficient permissions', {
|
||||
const errorMessage = 'OAuth2 callback failed because of insufficient permissions';
|
||||
LoggerProxy.error(errorMessage, {
|
||||
userId: req.user?.id,
|
||||
credentialId: state.cid,
|
||||
});
|
||||
const errorResponse = new ResponseHelper.NotFoundError(
|
||||
RESPONSE_ERROR_MESSAGES.NO_CREDENTIAL,
|
||||
);
|
||||
return ResponseHelper.sendErrorResponse(res, errorResponse);
|
||||
return renderCallbackError(res, errorMessage);
|
||||
}
|
||||
|
||||
let encryptionKey: string;
|
||||
try {
|
||||
encryptionKey = await UserSettings.getEncryptionKey();
|
||||
} catch (error) {
|
||||
throw new ResponseHelper.InternalServerError((error as IDataObject).message as string);
|
||||
}
|
||||
const encryptionKey = await UserSettings.getEncryptionKey();
|
||||
|
||||
const mode: WorkflowExecuteMode = 'internal';
|
||||
const timezone = config.getEnv('generic.timezone');
|
||||
@@ -251,14 +243,12 @@ oauth2CredentialController.get(
|
||||
decryptedDataOriginal.csrfSecret === undefined ||
|
||||
!token.verify(decryptedDataOriginal.csrfSecret as string, state.token)
|
||||
) {
|
||||
LoggerProxy.debug('OAuth2 callback state is invalid', {
|
||||
const errorMessage = 'The OAuth2 callback state is invalid!';
|
||||
LoggerProxy.debug(errorMessage, {
|
||||
userId: req.user?.id,
|
||||
credentialId: state.cid,
|
||||
});
|
||||
const errorResponse = new ResponseHelper.NotFoundError(
|
||||
'The OAuth2 callback state is invalid!',
|
||||
);
|
||||
return ResponseHelper.sendErrorResponse(res, errorResponse);
|
||||
return renderCallbackError(res, errorMessage);
|
||||
}
|
||||
|
||||
let options = {};
|
||||
@@ -298,12 +288,12 @@ oauth2CredentialController.get(
|
||||
}
|
||||
|
||||
if (oauthToken === undefined) {
|
||||
LoggerProxy.error('OAuth2 callback failed: unable to get access tokens', {
|
||||
const errorMessage = 'Unable to get OAuth2 access tokens!';
|
||||
LoggerProxy.error(errorMessage, {
|
||||
userId: req.user?.id,
|
||||
credentialId: state.cid,
|
||||
});
|
||||
const errorResponse = new ResponseHelper.NotFoundError('Unable to get access tokens!');
|
||||
return ResponseHelper.sendErrorResponse(res, errorResponse);
|
||||
return renderCallbackError(res, errorMessage);
|
||||
}
|
||||
|
||||
if (decryptedDataOriginal.oauthTokenData) {
|
||||
@@ -336,9 +326,7 @@ oauth2CredentialController.get(
|
||||
|
||||
return res.sendFile(pathResolve(TEMPLATES_DIR, 'oauth-callback.html'));
|
||||
} catch (error) {
|
||||
// Error response
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
return ResponseHelper.sendErrorResponse(res, error);
|
||||
return renderCallbackError(res, (error as Error).message);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user