feat: add gitlab authentication

This commit is contained in:
Ali BARIN
2022-05-04 00:38:31 +02:00
parent 2e2d371875
commit 39d82f17d7
9 changed files with 580 additions and 6 deletions

View File

@@ -21,6 +21,7 @@
"dependencies": {
"@automatisch/web": "0.1.0",
"@bull-board/express": "^3.10.1",
"@gitbeaker/node": "^35.6.0",
"@graphql-tools/graphql-file-loader": "^7.3.4",
"@graphql-tools/load": "^7.5.2",
"@octokit/oauth-methods": "^1.2.6",

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<svg width="256px" height="236px" viewBox="0 0 256 236" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
<g>
<path d="M128.07485,236.074667 L128.07485,236.074667 L175.17885,91.1043048 L80.9708495,91.1043048 L128.07485,236.074667 L128.07485,236.074667 Z" fill="#E24329"></path>
<path d="M128.07485,236.074423 L80.9708495,91.104061 L14.9557638,91.104061 L128.07485,236.074423 L128.07485,236.074423 Z" fill="#FC6D26"></path>
<path d="M14.9558857,91.1044267 L14.9558857,91.1044267 L0.641828571,135.159589 C-0.663771429,139.17757 0.766171429,143.57955 4.18438095,146.06275 L128.074971,236.074789 L14.9558857,91.1044267 L14.9558857,91.1044267 Z" fill="#FCA326"></path>
<path d="M14.9558857,91.1045486 L80.9709714,91.1045486 L52.6000762,3.79026286 C51.1408762,-0.703146667 44.7847619,-0.701927619 43.3255619,3.79026286 L14.9558857,91.1045486 L14.9558857,91.1045486 Z" fill="#E24329"></path>
<path d="M128.07485,236.074423 L175.17885,91.104061 L241.193935,91.104061 L128.07485,236.074423 L128.07485,236.074423 Z" fill="#FC6D26"></path>
<path d="M241.193935,91.1044267 L241.193935,91.1044267 L255.507992,135.159589 C256.813592,139.17757 255.38365,143.57955 251.96544,146.06275 L128.07485,236.074789 L241.193935,91.1044267 L241.193935,91.1044267 Z" fill="#FCA326"></path>
<path d="M241.193935,91.1045486 L175.17885,91.1045486 L203.549745,3.79026286 C205.008945,-0.703146667 211.365059,-0.701927619 212.824259,3.79026286 L241.193935,91.1045486 L241.193935,91.1045486 Z" fill="#E24329"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,101 @@
import { URLSearchParams } from 'url';
import axios from 'axios';
import crypto from 'crypto';
import { Gitlab } from '@gitbeaker/node';
import type {
IAuthentication,
IApp,
IField,
IJSONObject,
} from '@automatisch/types';
export default class Authentication implements IAuthentication {
appData: IApp;
connectionData: IJSONObject;
client: any;
scopes = [
'api',
'profile',
'email',
];
constructor(appData: IApp, connectionData: IJSONObject) {
this.connectionData = connectionData;
this.appData = appData;
if (connectionData?.accessToken) {
this.client = new Gitlab({
host: this.host,
oauthToken: connectionData?.accessToken as string,
});
}
}
get host() {
return `https://${this.connectionData.host}`;
}
get oauthRedirectUrl() {
return this.appData.fields.find(
(field: IField) => field.key == 'oAuthRedirectUrl'
).value;
}
async createAuthData() {
const state = crypto.randomUUID();
const searchParams = new URLSearchParams({
client_id: this.connectionData.applicationId as string,
redirect_uri: this.oauthRedirectUrl,
response_type: 'code',
scope: this.scopes.join(' '),
state,
});
const url = `${this.host}/oauth/authorize?${searchParams.toString()}`;
return { url };
}
async verifyCredentials() {
const params = new URLSearchParams({
client_id: this.connectionData.applicationId as string,
grant_type: 'authorization_code',
redirect_uri: this.oauthRedirectUrl,
code: this.connectionData.oauthVerifier as string,
client_secret: this.connectionData.secret as string,
});
const { data } = await axios.post(`${this.host}/oauth/token`, params.toString());
const accessToken = data.access_token;
const client = new Gitlab({
host: this.host,
oauthToken: accessToken,
});
const user = await client.Users.current();
return {
host: this.connectionData.host as string,
applicationId: this.connectionData.applicationId as string,
secret: this.connectionData.secret,
accessToken: data.access_token,
refreshToken: data.refresh_token,
expiresIn: data.expires_in,
tokenType: data.token_type,
userId: user.id,
screenName: user.name,
username: user.username,
};
}
async isStillVerified() {
try {
await this.client.Users.current();
return true;
} catch (err) {
return false;
}
}
}

View File

View File

@@ -0,0 +1,15 @@
import Authentication from './authentication';
import {
IService,
IAuthentication,
IApp,
IJSONObject,
} from '@automatisch/types';
export default class Gitlab implements IService {
authenticationClient: IAuthentication;
constructor(appData: IApp, connectionData: IJSONObject) {
this.authenticationClient = new Authentication(appData, connectionData);
}
}

View File

@@ -0,0 +1,238 @@
{
"name": "GitLab",
"key": "gitlab",
"iconUrl": "{BASE_URL}/apps/gitlab/assets/favicon.svg",
"docUrl": "https://automatisch.io/docs/gitlab",
"primaryColor": "2DAAE1",
"fields": [
{
"key": "oAuthRedirectUrl",
"label": "OAuth Redirect URL",
"type": "string",
"required": true,
"readOnly": true,
"value": "{WEB_APP_URL}/app/gitlab/connections/add",
"placeholder": null,
"description": "When asked to input an OAuth callback or redirect URL in GitLab OAuth, enter the URL above.",
"docUrl": "https://automatisch.io/docs/gitlab#oauth-redirect-url",
"clickToCopy": true
},
{
"key": "host",
"label": "GitLab Host",
"type": "string",
"required": true,
"readOnly": false,
"value": "gitlab.com",
"placeholder": null,
"description": "Only required if you host your own instance of GitLab. If you access GitLab by going to https://www.example.com, enter www.example.com here.",
"docUrl": "https://automatisch.io/docs/gitlab#host",
"clickToCopy": false
},
{
"key": "applicationId",
"label": "Application ID",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/gitlab#application-id",
"clickToCopy": false
},
{
"key": "secret",
"label": "Secret",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/gitlab#secret",
"clickToCopy": false
}
],
"authenticationSteps": [
{
"step": 1,
"type": "mutation",
"name": "createConnection",
"arguments": [
{
"name": "key",
"value": "{key}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "host",
"value": "{fields.host}"
},
{
"name": "applicationId",
"value": "{fields.applicationId}"
},
{
"name": "secret",
"value": "{fields.secret}"
}
]
}
]
},
{
"step": 2,
"type": "mutation",
"name": "createAuthData",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
}
]
},
{
"step": 3,
"type": "openWithPopup",
"name": "openAuthPopup",
"arguments": [
{
"name": "url",
"value": "{createAuthData.url}"
}
]
},
{
"step": 4,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "oauthVerifier",
"value": "{openAuthPopup.code}"
}
]
}
]
},
{
"step": 5,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
}
]
}
],
"reconnectionSteps": [
{
"step": 1,
"type": "mutation",
"name": "resetConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
},
{
"step": 2,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "host",
"value": "{fields.host}"
},
{
"name": "applicationId",
"value": "{fields.applicationId}"
},
{
"name": "secret",
"value": "{fields.secret}"
}
]
}
]
},
{
"step": 3,
"type": "mutation",
"name": "createAuthData",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
},
{
"step": 4,
"type": "openWithPopup",
"name": "openAuthPopup",
"arguments": [
{
"name": "url",
"value": "{createAuthData.url}"
}
]
},
{
"step": 5,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "oauthVerifier",
"value": "{openAuthPopup.code}"
}
]
}
]
},
{
"step": 6,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
}
]
}

View File

@@ -24,11 +24,7 @@ const createAuthData = async (
if (!connection.formattedData) { return null; }
const appInstance = new appClass(appData, {
consumerKey: connection.formattedData.consumerKey,
consumerSecret: connection.formattedData.consumerSecret,
});
const appInstance = new appClass(appData, connection.formattedData);
const authLink = await appInstance.authenticationClient.createAuthData();
await connection.$query().patch({

View File

@@ -133,6 +133,7 @@ enum AvailableAppsEnumType {
firebase
flickr
github
gitlab
postgresql
smtp
twilio