feat: Implement createAuthLink mutation
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
"morgan": "^1.10.0",
|
||||
"objection": "^2.2.17",
|
||||
"pg": "^8.7.1",
|
||||
"twitter-api-v2": "1.6.0",
|
||||
"winston": "^3.3.3"
|
||||
},
|
||||
"contributors": [
|
||||
|
24
packages/backend/src/apps/twitter/index.ts
Normal file
24
packages/backend/src/apps/twitter/index.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import TwitterApi from 'twitter-api-v2';
|
||||
import App from '../../models/app';
|
||||
import Field from '../../types/field';
|
||||
|
||||
export default class Twitter {
|
||||
client: any
|
||||
appData: any
|
||||
|
||||
constructor(credentialsData: any) {
|
||||
this.client = new TwitterApi({
|
||||
appKey: credentialsData.consumerKey,
|
||||
appSecret: credentialsData.consumerSecret
|
||||
});
|
||||
|
||||
this.appData = App.findOneByName('twitter')
|
||||
}
|
||||
|
||||
async createAuthLink() {
|
||||
const appFields = this.appData.fields.find((field: Field) => field.key == 'oAuthRedirectUrl')
|
||||
const callbackUrl = appFields.value;
|
||||
|
||||
return this.client.generateAuthLink(callbackUrl);
|
||||
}
|
||||
}
|
@@ -12,7 +12,7 @@
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"readOnly": true,
|
||||
"value": "http://localhost:3000/sample",
|
||||
"value": "http://localhost:3001/app/twitter/connections/add",
|
||||
"placeholder": null,
|
||||
"description": "When asked to input an OAuth callback or redirect URL in Twitter OAuth, enter the URL above.",
|
||||
"docUrl": "https://automatisch.io/docs/twitter#oauth-redirect-url",
|
||||
@@ -84,6 +84,17 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"step": 2,
|
||||
"type": "mutation",
|
||||
"name": "createAuthLink",
|
||||
"fields": [
|
||||
{
|
||||
"name": "id",
|
||||
"value": "{response.credentialId}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
35
packages/backend/src/graphql/mutations/create-auth-link.ts
Normal file
35
packages/backend/src/graphql/mutations/create-auth-link.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { GraphQLNonNull, GraphQLInt } from 'graphql';
|
||||
import Credential from '../../models/credential';
|
||||
import authLinkType from '../types/auth-link';
|
||||
import User from '../../models/user';
|
||||
|
||||
type Params = {
|
||||
credentialId: number,
|
||||
}
|
||||
const createAuthLinkResolver = async (params: Params) => {
|
||||
const user = await User.query().findOne({
|
||||
email: 'user@automatisch.com'
|
||||
})
|
||||
|
||||
const credential = await Credential.query().findOne({
|
||||
user_id: user.id,
|
||||
id: params.credentialId
|
||||
})
|
||||
|
||||
const appClass = (await import(`../../apps/${credential.key}`)).default;
|
||||
|
||||
const appInstance = new appClass(credential.data)
|
||||
const authLink = await appInstance.createAuthLink();
|
||||
|
||||
return authLink;
|
||||
}
|
||||
|
||||
const createAuthLink = {
|
||||
type: authLinkType,
|
||||
args: {
|
||||
credentialId: { type: GraphQLNonNull(GraphQLInt) },
|
||||
},
|
||||
resolve: (_: any, params: Params) => createAuthLinkResolver(params)
|
||||
};
|
||||
|
||||
export default createAuthLink;
|
@@ -1,10 +1,12 @@
|
||||
import { GraphQLObjectType } from 'graphql';
|
||||
import createCredential from './mutations/create-credential';
|
||||
import createAuthLink from './mutations/create-auth-link';
|
||||
|
||||
const rootMutation = new GraphQLObjectType({
|
||||
name: 'Mutation',
|
||||
fields: {
|
||||
createCredential: createCredential
|
||||
createCredential: createCredential,
|
||||
createAuthLink: createAuthLink
|
||||
}
|
||||
});
|
||||
|
||||
|
10
packages/backend/src/graphql/types/auth-link.ts
Normal file
10
packages/backend/src/graphql/types/auth-link.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { GraphQLObjectType, GraphQLString } from 'graphql';
|
||||
|
||||
const authLinkType = new GraphQLObjectType({
|
||||
name: 'authLink',
|
||||
fields: {
|
||||
url: { type: GraphQLString }
|
||||
}
|
||||
})
|
||||
|
||||
export default authLinkType;
|
@@ -4,6 +4,7 @@ import twitterCredentialType from './twitter-credential';
|
||||
const credentialType = new GraphQLObjectType({
|
||||
name: 'credential',
|
||||
fields: {
|
||||
id: { type: GraphQLString },
|
||||
key: { type: GraphQLString },
|
||||
displayName: { type: GraphQLString },
|
||||
data: { type: twitterCredentialType },
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import Base from './base'
|
||||
import User from './user'
|
||||
|
||||
class Credential extends Base {
|
||||
id!: number
|
||||
@@ -22,6 +23,17 @@ class Credential extends Base {
|
||||
verified: { type: 'boolean' },
|
||||
}
|
||||
}
|
||||
|
||||
static relationMappings = () => ({
|
||||
credentials: {
|
||||
relation: Base.BelongsToOneRelation,
|
||||
modelClass: User,
|
||||
join: {
|
||||
from: 'credentials.user_id',
|
||||
to: 'users.id',
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default Credential;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { QueryContext, ModelOptions } from 'objection';
|
||||
import Base from './base'
|
||||
import Base from './base';
|
||||
import Credential from './credential';
|
||||
import bcrypt from 'bcrypt';
|
||||
|
||||
class User extends Base {
|
||||
@@ -20,6 +21,17 @@ class User extends Base {
|
||||
}
|
||||
}
|
||||
|
||||
static relationMappings = () => ({
|
||||
credentials: {
|
||||
relation: Base.HasManyRelation,
|
||||
modelClass: Credential,
|
||||
join: {
|
||||
from: 'users.id',
|
||||
to: 'credentials.user_id',
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
async generateHash() {
|
||||
this.password = await bcrypt.hash(this.password, 10);
|
||||
}
|
||||
|
14
packages/backend/src/types/field.d.ts
vendored
Normal file
14
packages/backend/src/types/field.d.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
type Field = {
|
||||
key: string,
|
||||
label: string,
|
||||
type: string,
|
||||
required: boolean,
|
||||
readOnly: boolean,
|
||||
value: string,
|
||||
placeholder: string,
|
||||
description: string,
|
||||
docUrl: string,
|
||||
clickToCopy: boolean
|
||||
}
|
||||
|
||||
export default Field;
|
@@ -15110,6 +15110,11 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
||||
|
||||
twitter-api-v2@1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/twitter-api-v2/-/twitter-api-v2-1.6.0.tgz#429a19aed338d2ccf17a0cd890e590b20bb6e768"
|
||||
integrity sha512-MLpHYyw06Ch0FLYZ8JvX4HZethpXRRtUetYe4HtPhcQvJgukvS8xKc1CG1nSuNDVZyZ1KN9ps6W3nHRZVxm+qg==
|
||||
|
||||
type-check@^0.4.0, type-check@~0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
|
||||
|
Reference in New Issue
Block a user