1
1
mirror of https://github.com/n8n-io/n8n.git synced 2024-11-10 12:35:46 +03:00

Add UI logic to support OAuth authentication flow

Add support in credentialsList to kickoff an OAuth2 authorization
flow. This enables users to authenticate and allow n8n to store
the resulting keys in the backend.
This commit is contained in:
Ram Yalamanchili 2020-01-01 22:49:18 -08:00
parent d2ea3ce877
commit cb73853680
4 changed files with 41 additions and 2 deletions

View File

@ -145,6 +145,8 @@ export interface IRestApi {
deleteExecutions(sendData: IExecutionDeleteFilter): Promise<void>; deleteExecutions(sendData: IExecutionDeleteFilter): Promise<void>;
retryExecution(id: string, loadWorkflow?: boolean): Promise<boolean>; retryExecution(id: string, loadWorkflow?: boolean): Promise<boolean>;
getTimezones(): Promise<IDataObject>; getTimezones(): Promise<IDataObject>;
OAuth2CredentialAuthorize(sendData: ICredentialsResponse): Promise<string>;
OAuth2Callback(code: string, state: string): Promise<string>;
} }
export interface IBinaryDisplayData { export interface IBinaryDisplayData {

View File

@ -25,10 +25,12 @@
<el-table-column property="updatedAt" label="Updated" class-name="clickable" sortable></el-table-column> <el-table-column property="updatedAt" label="Updated" class-name="clickable" sortable></el-table-column>
<el-table-column <el-table-column
label="Operations" label="Operations"
width="120"> width="180">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button title="Edit Credentials" @click.stop="editCredential(scope.row)" icon="el-icon-edit" circle></el-button> <el-button title="Edit Credentials" @click.stop="editCredential(scope.row)" icon="el-icon-edit" circle></el-button>
<el-button title="Delete Credentials" @click.stop="deleteCredential(scope.row)" type="danger" icon="el-icon-delete" circle></el-button> <el-button title="Delete Credentials" @click.stop="deleteCredential(scope.row)" type="danger" icon="el-icon-delete" circle></el-button>
<!-- Would be nice to have this button switch from connect to disconnect based on the credential status -->
<el-button title="Connect OAuth Credentials" @click.stop="OAuth2CredentialAuthorize(scope.row)" icon="el-icon-caret-right" v-if="scope.row.type == 'OAuth2Api'" circle></el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -91,6 +93,20 @@ export default mixins(
this.editCredentials = null; this.editCredentials = null;
this.credentialEditDialogVisible = true; this.credentialEditDialogVisible = true;
}, },
async OAuth2CredentialAuthorize (credential: ICredentialsResponse) {
let url;
try {
url = await this.restApi().OAuth2CredentialAuthorize(credential) as string;
} catch (error) {
this.$showError(error, 'OAuth Authorization Error', 'Error generating authorization URL:');
return;
}
const params = `scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no,width=0,height=0,left=-1000,top=-1000`;
const oauthPopup = window.open(url, 'OAuth2 Authorization', params);
console.log(oauthPopup);
},
editCredential (credential: ICredentialsResponse) { editCredential (credential: ICredentialsResponse) {
const editCredentials = { const editCredentials = {
id: credential.id, id: credential.id,
@ -124,7 +140,7 @@ export default mixins(
try { try {
this.credentials = JSON.parse(JSON.stringify(this.$store.getters.allCredentials)); this.credentials = JSON.parse(JSON.stringify(this.$store.getters.allCredentials));
} catch (error) { } catch (error) {
this.$showError(error, 'Proble loading credentials', 'There was a problem loading the credentials:'); this.$showError(error, 'Problem loading credentials', 'There was a problem loading the credentials:');
this.isDataLoading = false; this.isDataLoading = false;
return; return;
} }

View File

@ -252,6 +252,21 @@ export const restApi = Vue.extend({
return self.restApi().makeRestApiRequest('GET', `/credential-types`); return self.restApi().makeRestApiRequest('GET', `/credential-types`);
}, },
// Get OAuth2 Authorization URL using the stored credentials
OAuth2CredentialAuthorize: (sendData: ICredentialsResponse): Promise<string> => {
return self.restApi().makeRestApiRequest('GET', `/oauth2-credential/auth`, sendData);
},
// Verify OAuth2 provider callback and kick off token generation
OAuth2Callback: (code: string, state: string): Promise<string> => {
const sendData = {
'code': code,
'state': state
};
return self.restApi().makeRestApiRequest('POST', `/oauth2-credential/callback`, sendData);
},
// Returns the execution with the given name // Returns the execution with the given name
getExecution: async (id: string): Promise<IExecutionResponse> => { getExecution: async (id: string): Promise<IExecutionResponse> => {
const response = await self.restApi().makeRestApiRequest('GET', `/executions/${id}`); const response = await self.restApi().makeRestApiRequest('GET', `/executions/${id}`);

View File

@ -19,6 +19,12 @@ export default new Router({
sidebar: MainSidebar, sidebar: MainSidebar,
}, },
}, },
{
path: '/oauth2/callback',
name: 'OAuth2Callback',
components: {
},
},
{ {
path: '/workflow', path: '/workflow',
name: 'NodeViewNew', name: 'NodeViewNew',