diff --git a/lib/facts/identity-service.js b/lib/facts/identity-service.js new file mode 100644 --- /dev/null +++ b/lib/facts/identity-service.js @@ -0,0 +1,11 @@ +// @flow + +import { isDev } from '../utils/dev-utils.js'; + +const config: { defaultURL: string } = { + defaultURL: isDev + ? 'https://identity.staging.commtechnologies.org:50054' + : 'https://identity.commtechnologies.org:50054', +}; + +export default config; diff --git a/lib/types/identity-service-types.js b/lib/types/identity-service-types.js --- a/lib/types/identity-service-types.js +++ b/lib/types/identity-service-types.js @@ -18,3 +18,9 @@ +oneTimeContentPrekey: ?string, +oneTimeNotifPrekey: ?string, }; + +export type IdentityServiceAuthLayer = { + +userID: string, + +deviceID: string, + +commServicesAccessToken: string, +}; diff --git a/web/grpc/identity-service-client-wrapper.js b/web/grpc/identity-service-client-wrapper.js new file mode 100644 --- /dev/null +++ b/web/grpc/identity-service-client-wrapper.js @@ -0,0 +1,99 @@ +// @flow + +import invariant from 'invariant'; + +import identityServiceConfig from 'lib/facts/identity-service.js'; +import type { IdentityServiceAuthLayer } from 'lib/types/identity-service-types.js'; + +import { VersionInterceptor, AuthInterceptor } from './interceptor.js'; +import * as IdentityAuthClient from '../protobufs/identity-auth-client.cjs'; +import * as IdentityClient from '../protobufs/identity-client.cjs'; +import { Empty } from '../protobufs/identity-structs.cjs'; + +class IdentityServiceClientWrapper { + authClient: ?IdentityAuthClient.IdentityClientServicePromiseClient; + unauthorizedClient: ?IdentityClient.IdentityClientServicePromiseClient; + + constructor() { + this.authClient = null; + this.unauthorizedClient = null; + } + + determineSocketAddr(): string { + let identitySocketAddr; + const identityServiceConfigRaw = process.env.IDENTITY_SERVICE_CONFIG; + + if (identityServiceConfigRaw !== null) { + invariant( + typeof identityServiceConfigRaw === 'object', + 'identityServiceConfigRaw should be an object', + ); + identitySocketAddr = identityServiceConfigRaw.identitySocketAddr; + } + + return identitySocketAddr || identityServiceConfig.defaultURL; + } + + async initAuthClient(authLayer: IdentityServiceAuthLayer): Promise { + const { userID, deviceID, commServicesAccessToken } = authLayer; + + const identitySocketAddr = this.determineSocketAddr(); + + const versionInterceptor = new VersionInterceptor(); + const authInterceptor = new AuthInterceptor( + userID, + deviceID, + commServicesAccessToken, + ); + + const authClientOpts = { + unaryInterceptors: [versionInterceptor, authInterceptor], + }; + + this.authClient = new IdentityAuthClient.IdentityClientServicePromiseClient( + identitySocketAddr, + null, + authClientOpts, + ); + } + + async initUnauthorizedClient(): Promise { + const identitySocketAddr = this.determineSocketAddr(); + + const versionInterceptor = new VersionInterceptor(); + + const unauthorizedClientOpts = { + unaryInterceptors: [versionInterceptor], + }; + + this.unauthorizedClient = + new IdentityClient.IdentityClientServicePromiseClient( + identitySocketAddr, + null, + unauthorizedClientOpts, + ); + } + + async deleteUser( + userID: string, + deviceID: string, + accessToken: string, + ): Promise { + if (!this.authClient) { + const authLayer: IdentityServiceAuthLayer = { + userID, + deviceID, + commServicesAccessToken: accessToken, + }; + await this.initAuthClient(authLayer); + } + + if (this.authClient) { + await this.authClient.deleteUser(new Empty()); + } else { + throw new Error('Identity service client is not initialized'); + } + } +} + +export { IdentityServiceClientWrapper };