diff --git a/packages/backend/src/apps/twitter/index.ts b/packages/backend/src/apps/twitter/index.ts index 79ab8444..4115558b 100644 --- a/packages/backend/src/apps/twitter/index.ts +++ b/packages/backend/src/apps/twitter/index.ts @@ -4,15 +4,19 @@ import Field from '../../types/field'; export default class Twitter { client: any + credentialsData: any appData: any constructor(credentialsData: any) { this.client = new TwitterApi({ appKey: credentialsData.consumerKey, - appSecret: credentialsData.consumerSecret + appSecret: credentialsData.consumerSecret, + accessToken: credentialsData.accessToken, + accessSecret: credentialsData.accessSecret }); - this.appData = App.findOneByName('twitter') + this.credentialsData = credentialsData; + this.appData = App.findOneByName('twitter'); } async createAuthLink() { @@ -21,4 +25,17 @@ export default class Twitter { return this.client.generateAuthLink(callbackUrl); } + + async verifyCredentials() { + const verifiedCredentials = await this.client.login(this.credentialsData.oauthVerifier) + + return { + consumerKey: this.credentialsData.consumerKey, + consumerSecret: this.credentialsData.consumerSecret, + accessToken: verifiedCredentials.accessToken, + accessSecret: verifiedCredentials.accessSecret, + userId: verifiedCredentials.userId, + screenName: verifiedCredentials.screenName + } + } } diff --git a/packages/backend/src/apps/twitter/info.json b/packages/backend/src/apps/twitter/info.json index 6cdbe542..fdb3a680 100644 --- a/packages/backend/src/apps/twitter/info.json +++ b/packages/backend/src/apps/twitter/info.json @@ -90,6 +90,27 @@ "value": "{createAuthLink.url}" } ] + }, + { + "step": 4, + "type": "mutation", + "name": "updateCredential", + "fields": [ + { + "name": "id", + "value": "{createCredential.id}" + }, + { + "name": "data", + "value": null, + "fields": [ + { + "name": "oauthVerifier", + "value": "{openTwitterAuthPopup.oauth_verifier}" + } + ] + } + ] } ] } diff --git a/packages/backend/src/graphql/mutations/create-auth-link.ts b/packages/backend/src/graphql/mutations/create-auth-link.ts index de2f0428..857dbe32 100644 --- a/packages/backend/src/graphql/mutations/create-auth-link.ts +++ b/packages/backend/src/graphql/mutations/create-auth-link.ts @@ -17,6 +17,16 @@ const createAuthLinkResolver = async (params: Params, req: RequestWithCurrentUse const appInstance = new appClass(credential.data) const authLink = await appInstance.createAuthLink(); + await credential.$query().patch({ + data: { + ...credential.data, + url: authLink.url, + accessToken: authLink.oauth_token, + accessSecret: authLink.oauth_token_secret, + }, + verified: authLink.oauth_callback_confirmed === 'true' ? true : false + }) + return authLink; } diff --git a/packages/backend/src/graphql/mutations/update-credential.ts b/packages/backend/src/graphql/mutations/update-credential.ts new file mode 100644 index 00000000..19c20c3d --- /dev/null +++ b/packages/backend/src/graphql/mutations/update-credential.ts @@ -0,0 +1,45 @@ +import { GraphQLString, GraphQLNonNull } from 'graphql'; +import Credential from '../../models/credential'; +import credentialType from '../types/credential'; +import twitterCredentialInputType from '../types/twitter-credential-input'; +import RequestWithCurrentUser from '../../types/express/request-with-current-user'; + +type Params = { + id: string, + data: object +} +const updateCredentialResolver = async (params: Params, req: RequestWithCurrentUser) => { + let credential = await Credential.query().findOne({ + user_id: req.currentUser.id, + id: params.id + }) + + credential = await credential.$query().patchAndFetch({ + data: { + ...credential.data, + ...params.data + } + }) + + const appClass = (await import(`../../apps/${credential.key}`)).default; + + const appInstance = new appClass(credential.data) + const verifiedCredentials = await appInstance.verifyCredentials(); + + credential = await credential.$query().patchAndFetch({ + data: verifiedCredentials + }) + + return credential; +} + +const updateCredential = { + type: credentialType, + args: { + id: { type: GraphQLNonNull(GraphQLString) }, + data: { type: GraphQLNonNull(twitterCredentialInputType) } + }, + resolve: (_: any, params: Params, req: RequestWithCurrentUser) => updateCredentialResolver(params, req) +}; + +export default updateCredential; diff --git a/packages/backend/src/graphql/root-mutation.ts b/packages/backend/src/graphql/root-mutation.ts index 3d0f4f8f..8c34ad29 100644 --- a/packages/backend/src/graphql/root-mutation.ts +++ b/packages/backend/src/graphql/root-mutation.ts @@ -1,12 +1,14 @@ import { GraphQLObjectType } from 'graphql'; import createCredential from './mutations/create-credential'; import createAuthLink from './mutations/create-auth-link'; +import updateCredential from './mutations/update-credential'; const rootMutation = new GraphQLObjectType({ name: 'Mutation', fields: { createCredential: createCredential, - createAuthLink: createAuthLink + createAuthLink: createAuthLink, + updateCredential: updateCredential } }); diff --git a/packages/backend/src/graphql/types/credential.ts b/packages/backend/src/graphql/types/credential.ts index e3e3d29a..a4fcd445 100644 --- a/packages/backend/src/graphql/types/credential.ts +++ b/packages/backend/src/graphql/types/credential.ts @@ -1,4 +1,4 @@ -import { GraphQLObjectType, GraphQLString } from 'graphql'; +import { GraphQLObjectType, GraphQLString, GraphQLBoolean } from 'graphql'; import twitterCredentialType from './twitter-credential'; const credentialType = new GraphQLObjectType({ @@ -7,6 +7,7 @@ const credentialType = new GraphQLObjectType({ id: { type: GraphQLString }, key: { type: GraphQLString }, data: { type: twitterCredentialType }, + verified: { type: GraphQLBoolean }, } }) diff --git a/packages/backend/src/graphql/types/twitter-credential-input.ts b/packages/backend/src/graphql/types/twitter-credential-input.ts index 743951bf..3aee03ed 100644 --- a/packages/backend/src/graphql/types/twitter-credential-input.ts +++ b/packages/backend/src/graphql/types/twitter-credential-input.ts @@ -5,6 +5,7 @@ const twitterCredentialInputType = new GraphQLInputObjectType({ fields: { consumerKey: { type: GraphQLString }, consumerSecret: { type: GraphQLString }, + oauthVerifier: { type: GraphQLString }, } }) diff --git a/packages/backend/src/models/credential.ts b/packages/backend/src/models/credential.ts index 4541be31..ff5a84e7 100644 --- a/packages/backend/src/models/credential.ts +++ b/packages/backend/src/models/credential.ts @@ -4,8 +4,9 @@ import User from './user' class Credential extends Base { id!: number key!: string - data!: string + data!: any userId!: number + verified: boolean static tableName = 'credentials';