Files
automatisch/packages/backend/src/apps/github/authentication.ts
2022-10-03 17:10:16 +02:00

96 lines
2.5 KiB
TypeScript

import type {
IAuthentication,
IApp,
IField,
IJSONObject,
} from '@automatisch/types';
import createHttpClient, { IHttpClient } from '../../helpers/http-client';
import { URLSearchParams } from 'url';
export default class Authentication implements IAuthentication {
appData: IApp;
connectionData: IJSONObject;
scopes: string[] = ['read:org', 'repo', 'user'];
client: IHttpClient;
constructor(appData: IApp, connectionData: IJSONObject) {
this.connectionData = connectionData;
this.appData = appData;
this.client = createHttpClient({ baseURL: 'https://github.com' });
}
get oauthRedirectUrl(): string {
return this.appData.fields.find(
(field: IField) => field.key == 'oAuthRedirectUrl'
).value;
}
async createAuthData(): Promise<{ url: string }> {
const searchParams = new URLSearchParams({
client_id: this.connectionData.consumerKey as string,
redirect_uri: this.oauthRedirectUrl,
scope: this.scopes.join(','),
});
const url = `https://github.com/login/oauth/authorize?${searchParams.toString()}`;
return {
url,
};
}
async verifyCredentials() {
const response = await this.client.post('/login/oauth/access_token', {
client_id: this.connectionData.consumerKey,
client_secret: this.connectionData.consumerSecret,
code: this.connectionData.oauthVerifier,
});
const data = Object.fromEntries(new URLSearchParams(response.data));
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() {
const basicAuthToken = Buffer.from(
this.connectionData.consumerKey + ':' + this.connectionData.consumerSecret
).toString('base64');
const headers = {
Authorization: `Basic ${basicAuthToken}`,
};
const body = {
access_token: this.connectionData.accessToken,
};
return await this.client.post(
`https://api.github.com/applications/${this.connectionData.consumerKey}/token`,
body,
{ headers }
);
}
async isStillVerified() {
try {
await this.getTokenInfo();
return true;
} catch {
return false;
}
}
}