feat: introduce github authentication

This commit is contained in:
Ali BARIN
2021-10-26 23:41:25 +02:00
parent 2f7cde95da
commit 72476ceb8b
5 changed files with 325 additions and 2 deletions

View File

@@ -15,6 +15,7 @@
"db:migrate": "knex migrate:latest"
},
"dependencies": {
"@octokit/oauth-methods": "^1.2.6",
"axios": "0.24.0",
"bcrypt": "^5.0.1",
"cors": "^2.8.5",

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg"
aria-label="GitHub" role="img"
viewBox="0 0 512 512"><rect
width="512" height="512"
rx="15%"
fill="#1B1817"/><path fill="#fff" d="M335 499c14 0 12 17 12 17H165s-2-17 12-17c13 0 16-6 16-12l-1-50c-71 16-86-28-86-28-12-30-28-37-28-37-24-16 1-16 1-16 26 2 40 26 40 26 22 39 59 28 74 22 2-17 9-28 16-35-57-6-116-28-116-126 0-28 10-51 26-69-3-6-11-32 3-67 0 0 21-7 70 26 42-12 86-12 128 0 49-33 70-26 70-26 14 35 6 61 3 67 16 18 26 41 26 69 0 98-60 120-117 126 10 8 18 24 18 48l-1 70c0 6 3 12 16 12z"/></svg>

After

Width:  |  Height:  |  Size: 542 B

View File

@@ -0,0 +1,77 @@
import {
getWebFlowAuthorizationUrl,
exchangeWebFlowCode,
checkToken,
} from '@octokit/oauth-methods';
import App from '../../models/app';
import Field from '../../types/field';
export default class Github {
connectionData: any
appData: any
scopes: string[] = ['repo']
constructor(connectionData: any) {
this.connectionData = connectionData;
this.appData = App.findOneByKey('github');
}
get oauthRedirectUrl() {
return this.appData.fields.find((field: Field) => field.key == 'oAuthRedirectUrl').value;
}
async createAuthData() {
const { url } = await getWebFlowAuthorizationUrl({
clientType: "oauth-app",
clientId: this.connectionData.consumerKey,
redirectUrl: this.oauthRedirectUrl,
scopes: this.scopes,
});
return {
url: url,
};
}
async verifyCredentials() {
const { data, authentication } = await exchangeWebFlowCode({
clientType: "oauth-app",
clientId: this.connectionData.consumerKey,
clientSecret: this.connectionData.consumerSecret,
code: this.connectionData.oauthVerifier,
});
this.connectionData.accessToken = data.access_token;
const tokenInfo = await this.getTokenInfo();
return {
consumerKey: this.connectionData.consumerKey,
consumerSecret: this.connectionData.consumerSecret,
accessToken: data.access_token,
scope: data.scope,
tokenType: data.token_type,
userId: tokenInfo.data.user.id,
screenName: tokenInfo.data.user.login,
}
}
async getTokenInfo() {
return checkToken({
clientType: "oauth-app",
clientId: this.connectionData.consumerKey,
clientSecret: this.connectionData.consumerSecret,
token: this.connectionData.accessToken,
});
}
async isStillVerified() {
try {
await this.getTokenInfo();
return true;
} catch {
return false;
}
}
}

View File

@@ -0,0 +1,218 @@
{
"name": "Github",
"key": "github",
"iconUrl": "{BASE_URL}/apps/github/assets/favicon.svg",
"docUrl": "https://automatisch.io/docs/github",
"primaryColor": "000000",
"fields": [
{
"key": "oAuthRedirectUrl",
"label": "OAuth Redirect URL",
"type": "string",
"required": true,
"readOnly": true,
"value": "https://localhost:3001/app/github/connections/add",
"placeholder": null,
"description": "When asked to input an OAuth callback or redirect URL in Github OAuth, enter the URL above.",
"docUrl": "https://automatisch.io/docs/github#oauth-redirect-url",
"clickToCopy": true
},
{
"key": "consumerKey",
"label": "Consumer Key",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/github#consumer-key",
"clickToCopy": false
},
{
"key": "consumerSecret",
"label": "Consumer Secret",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/github#consumer-secret",
"clickToCopy": false
}
],
"authenticationSteps": [
{
"step": 1,
"type": "mutation",
"name": "createConnection",
"arguments": [
{
"name": "key",
"value": "{key}"
},
{
"name": "data",
"value": null,
"properties": [
{
"name": "consumerKey",
"value": "{fields.consumerKey}"
},
{
"name": "consumerSecret",
"value": "{fields.consumerSecret}"
}
]
}
]
},
{
"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": "data",
"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": "data",
"value": null,
"properties": [
{
"name": "consumerKey",
"value": "{fields.consumerKey}"
},
{
"name": "consumerSecret",
"value": "{fields.consumerSecret}"
}
]
}
]
},
{
"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": "data",
"value": null,
"properties": [
{
"name": "oauthVerifier",
"value": "{openAuthPopup.code}"
}
]
}
]
},
{
"step": 6,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
}
]
}