fix(core): Open oauth callback endpoints to be public (#3168)

This commit is contained in:
Omar Ajoue 2022-04-25 10:51:50 +02:00 committed by GitHub
parent 0448feec56
commit 01807d6136
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 13 deletions

View file

@ -753,3 +753,13 @@ export async function getCredentialForUser(
return sharedCredential.credentials as ICredentialsDb;
}
/**
* Get a credential without user check
*/
export async function getCredentialWithoutUser(
credentialId: string,
): Promise<ICredentialsDb | undefined> {
const credential = await Db.collections.Credentials.findOne(credentialId);
return credential;
}

View file

@ -137,6 +137,7 @@ import {
WorkflowHelpers,
WorkflowRunner,
getCredentialForUser,
getCredentialWithoutUser,
} from '.';
import config from '../config';
@ -1822,18 +1823,18 @@ class App {
LoggerProxy.error(
'OAuth1 callback failed because of insufficient parameters received',
{
userId: req.user.id,
userId: req.user?.id,
credentialId,
},
);
return ResponseHelper.sendErrorResponse(res, errorResponse);
}
const credential = await getCredentialForUser(credentialId, req.user);
const credential = await getCredentialWithoutUser(credentialId);
if (!credential) {
LoggerProxy.error('OAuth1 callback failed because of insufficient user permissions', {
userId: req.user.id,
userId: req.user?.id,
credentialId,
});
const errorResponse = new ResponseHelper.ResponseError(
@ -1883,7 +1884,7 @@ class App {
oauthToken = await requestPromise(options);
} catch (error) {
LoggerProxy.error('Unable to fetch tokens for OAuth1 callback', {
userId: req.user.id,
userId: req.user?.id,
credentialId,
});
const errorResponse = new ResponseHelper.ResponseError(
@ -1913,13 +1914,13 @@ class App {
await Db.collections.Credentials!.update(credentialId, newCredentialsData);
LoggerProxy.verbose('OAuth1 callback successful for new credential', {
userId: req.user.id,
userId: req.user?.id,
credentialId,
});
res.sendFile(pathResolve(__dirname, '../../templates/oauth-callback.html'));
} catch (error) {
LoggerProxy.error('OAuth1 callback failed because of insufficient user permissions', {
userId: req.user.id,
userId: req.user?.id,
credentialId: req.query.cid,
});
// Error response
@ -2084,11 +2085,11 @@ class App {
return ResponseHelper.sendErrorResponse(res, errorResponse);
}
const credential = await getCredentialForUser(state.cid, req.user);
const credential = await getCredentialWithoutUser(state.cid);
if (!credential) {
LoggerProxy.error('OAuth2 callback failed because of insufficient permissions', {
userId: req.user.id,
userId: req.user?.id,
credentialId: state.cid,
});
const errorResponse = new ResponseHelper.ResponseError(
@ -2129,7 +2130,7 @@ class App {
!token.verify(decryptedDataOriginal.csrfSecret as string, state.token)
) {
LoggerProxy.debug('OAuth2 callback state is invalid', {
userId: req.user.id,
userId: req.user?.id,
credentialId: state.cid,
});
const errorResponse = new ResponseHelper.ResponseError(
@ -2180,7 +2181,7 @@ class App {
if (oauthToken === undefined) {
LoggerProxy.error('OAuth2 callback failed: unable to get access tokens', {
userId: req.user.id,
userId: req.user?.id,
credentialId: state.cid,
});
const errorResponse = new ResponseHelper.ResponseError(
@ -2214,7 +2215,7 @@ class App {
// Save the credentials in DB
await Db.collections.Credentials!.update(state.cid, newCredentialsData);
LoggerProxy.verbose('OAuth2 callback successful for new credential', {
userId: req.user.id,
userId: req.user?.id,
credentialId: state.cid,
});

View file

@ -66,6 +66,8 @@ export function addRoutes(this: N8nApp, ignoredEndpoints: string[], restEndpoint
req.url.startsWith(`/${restEndpoint}/forgot-password`) ||
req.url.startsWith(`/${restEndpoint}/resolve-password-token`) ||
req.url.startsWith(`/${restEndpoint}/change-password`) ||
req.url.startsWith(`/${restEndpoint}/oauth2-credential/callback`) ||
req.url.startsWith(`/${restEndpoint}/oauth1-credential/callback`) ||
isAuthExcluded(req.url, ignoredEndpoints)
) {
return next();

View file

@ -237,12 +237,16 @@ export declare namespace OAuthRequest {
{},
{},
{ oauth_verifier: string; oauth_token: string; cid: string }
>;
> & {
user?: User;
};
}
namespace OAuth2Credential {
type Auth = OAuth1Credential.Auth;
type Callback = AuthenticatedRequest<{}, {}, {}, { code: string; state: string }>;
type Callback = AuthenticatedRequest<{}, {}, {}, { code: string; state: string }> & {
user?: User;
};
}
}