diff --git a/docs/customization.md b/docs/customization.md index 332d65d..6717578 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -19,7 +19,7 @@ - [SecurityIntros](#securityintros) - [SecurityQuestions](#securityquestions) - [SecuritySummary](#securitysummary) - - [SsoConfirm](#ssoconfirm) + - [SocialEmailConfirm](#socialemailconfirm) - [TransactionRequest](#transactionrequest) - [ContractInteraction](#contractinteraction) - [SignatureRequest](#signaturerequest) @@ -81,7 +81,7 @@ Holds localization settings. - `securityIntros` [\](#securityintros) The settings for `SecurityIntros` screen. - `securityQuestions` [\](#securityquestions) The settings for `SecurityQuestions` screen. - `securitySummary` [\](#securitysummary) The settings for `SecuritySummary` screen. -- `ssoConfirm` [\](#ssoconfirm) The settings for `SsoConfirm` screen. +- `socialEmailConfirm` [\](#socialemailconfirm) The settings for `SocialEmailConfirm` screen. ### Common @@ -166,9 +166,9 @@ Holds localization settings for `SecuritySummary` screen. - `title` [\](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type) Title text - `question` [\](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type) Question text -### SsoConfirm +### SocialEmailConfirm -Holds localization settings for `SsoConfirm` screen. +Holds localization settings for `SocialEmailConfirm` screen. - `title` [\](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type) Title text - `headline` [\](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type) Headline text diff --git a/docs/usage.md b/docs/usage.md index 006c231..c7c6ffa 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -147,16 +147,9 @@ enum enum ErrorCode { insecurePinCode = 155704, hintsMatchAnswers = 155705, networkError = 155706, - biometricsSettingNotEnabled = 155708, - deviceNotSupportBiometrics = 155709, - biometricsKeyPermanentlyInvalidated = 155710, - biometricsUserSkip = 155711, - biometricsUserDisableForPin = 155712, - biometricsUserLockout = 155713, - biometricsUserLockoutPermanent = 155714, - biometricsUserNotAllowPermission = 155715, - biometricsInternalError = 155716, - invalidUserSecret= 155718, + userSecretMissing = 155717, + invalidUserTokenFormat= 155718, + userTokenMismatch = 155719, walletIdNotFound = 156001, tokenIdNotFound = 156002, transactionIdNotFound = 156003, @@ -271,8 +264,8 @@ Holds the OAuth information. - `provider` [\](#socialloginprovider) Social login - `scope` [\](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type) OAuth scope -- ssoUserUUID [\](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type) SSO user UUID -- `ssoUserInfo` [\](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#objects) SSO user information +- socialUserUUID [\](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type) Social login user UUID +- `socialUserInfo` [\](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#objects) Social login user information - email [\](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type) Email - name [\](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type) Name - phone [\](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type) Phone diff --git a/examples/js-example/package.json b/examples/js-example/package.json index 415ed1c..b4173f5 100644 --- a/examples/js-example/package.json +++ b/examples/js-example/package.json @@ -4,10 +4,13 @@ "main": "index.js", "license": "MIT", "dependencies": { - "@circle-fin/w3s-pw-web-sdk": "^1.0.0", + "@circle-fin/w3s-pw-web-sdk": "^1.1.1", + "buffer": "^6.0.3", "html-webpack-plugin": "^5.5.3", "jquery": "^3.7.1", "live-server": "^1.2.2", + "node-polyfill-webpack-plugin": "^4.0.0", + "process": "^0.11.10", "webpack": "^5.89.0", "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.15.1" diff --git a/examples/js-example/webpack.config.js b/examples/js-example/webpack.config.js index b5b8825..43192c4 100644 --- a/examples/js-example/webpack.config.js +++ b/examples/js-example/webpack.config.js @@ -1,6 +1,7 @@ const path = require('path') const webpack = require('webpack') const HtmlWebpackPlugin = require('html-webpack-plugin') +const NodePolyfillPlugin = require('node-polyfill-webpack-plugin') module.exports = { entry: './src/index.js', @@ -16,7 +17,17 @@ module.exports = { $: 'jquery', jQuery: 'jquery', }), + new NodePolyfillPlugin(), + new webpack.ProvidePlugin({ + process: 'process/browser', + Buffer: ['buffer', 'Buffer'], + }) ], + resolve: { + alias: { + process: 'process/browser', + }, + }, devServer: { static: { directory: path.join(__dirname, 'dist'), diff --git a/examples/react-example/config-overrides.js b/examples/react-example/config-overrides.js new file mode 100644 index 0000000..c184d0f --- /dev/null +++ b/examples/react-example/config-overrides.js @@ -0,0 +1,30 @@ +const webpack = require('webpack') + +module.exports = function override(config) { + const fallback = config.resolve.fallback || {} + + Object.assign(fallback, { + buffer: require.resolve('buffer/'), + crypto: require.resolve('crypto-browserify'), + stream: require.resolve('stream-browserify'), + util: require.resolve('util/'), + vm: require.resolve('vm-browserify'), + 'process/browser': require.resolve('process/browser'), + }) + + config.resolve.fallback = fallback + config.plugins = (config.plugins || []).concat([ + new webpack.ProvidePlugin({ + process: 'process/browser', + Buffer: ['buffer', 'Buffer'], + }), + ]) + config.module.rules.unshift({ + test: /\.m?js$/, + resolve: { + fullySpecified: false, + }, + }) + + return config +} diff --git a/examples/react-example/package.json b/examples/react-example/package.json index bbdb655..3424adf 100644 --- a/examples/react-example/package.json +++ b/examples/react-example/package.json @@ -3,18 +3,25 @@ "version": "0.1.0", "private": true, "dependencies": { - "@circle-fin/w3s-pw-web-sdk": "^1.0.0", + "@circle-fin/w3s-pw-web-sdk": "^1.1.1", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "buffer": "^6.0.3", + "crypto-browserify": "^3.12.0", + "process": "^0.11.10", + "react": "^18.3.1", + "react-app-rewired": "^2.2.1", + "react-dom": "^18.3.1", "react-scripts": "5.0.1", + "stream-browserify": "^3.0.0", + "util": "^0.12.5", + "vm-browserify": "^1.1.2", "web-vitals": "^2.1.4" }, "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", + "start": "react-app-rewired start", + "build": "react-app-rewired build", "test": "react-scripts test", "eject": "react-scripts eject" }, diff --git a/examples/vue-example/package.json b/examples/vue-example/package.json index 6580ee8..2a71ac7 100644 --- a/examples/vue-example/package.json +++ b/examples/vue-example/package.json @@ -8,7 +8,10 @@ "preview": "vite preview" }, "dependencies": { - "@circle-fin/w3s-pw-web-sdk": "^1.0.0", + "@circle-fin/w3s-pw-web-sdk": "^1.1.1", + "buffer": "^6.0.3", + "process": "^0.11.10", + "vite-plugin-node-polyfills": "^0.22.0", "vue": "^3.2.47" }, "devDependencies": { diff --git a/examples/vue-example/vite.config.js b/examples/vue-example/vite.config.js index de5cb31..0a6d6e3 100644 --- a/examples/vue-example/vite.config.js +++ b/examples/vue-example/vite.config.js @@ -1,14 +1,14 @@ +import vue from '@vitejs/plugin-vue' import { fileURLToPath, URL } from 'node:url' - import { defineConfig } from 'vite' -import vue from '@vitejs/plugin-vue' +import { nodePolyfills } from 'vite-plugin-node-polyfills' // https://vitejs.dev/config/ export default defineConfig({ - plugins: [vue()], + plugins: [nodePolyfills(), vue()], resolve: { alias: { - '@': fileURLToPath(new URL('./src', import.meta.url)) - } - } + '@': fileURLToPath(new URL('./src', import.meta.url)), + }, + }, }) diff --git a/package.json b/package.json index acc9524..9061419 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@circle-fin/w3s-pw-web-sdk", - "version": "1.1.0", + "version": "1.1.2", "description": "Javascript/Typescript SDK for Circle Programmable Wallets", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/index.test.ts b/src/index.test.ts index a930922..cafb1b6 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -45,7 +45,7 @@ describe('W3SSdk', () => { expect(addEventListenerSpy).toHaveBeenCalledWith( 'message', expect.any(Function), - false + false, ) }) @@ -97,7 +97,7 @@ describe('W3SSdk', () => { code: 1, message: 'Some error', } as Error, - undefined + undefined, ) }) }) diff --git a/src/index.ts b/src/index.ts index 6db53f8..3b1ba36 100644 --- a/src/index.ts +++ b/src/index.ts @@ -22,6 +22,8 @@ import { import { decode } from 'jsonwebtoken' import { v4 as uuidv4 } from 'uuid' +import packageInfo from '../package.json' + import { SocialLoginProvider } from './types' import type { @@ -43,12 +45,10 @@ import type { FirebaseApp } from 'firebase/app' import type { UserCredential } from 'firebase/auth' import type { JwtPayload } from 'jsonwebtoken' -const packageInfo = require('../package.json') as { version: string } - export class W3SSdk { private readonly serviceUrl = 'https://pw-auth.circle.com' private static instance: W3SSdk | null = null - private readonly iframe: HTMLIFrameElement + private readonly iframe!: HTMLIFrameElement private readonly window: Window = window private configs?: Configs private challenge?: Challenge @@ -181,7 +181,7 @@ export class W3SSdk { code: 155140, message: 'Invalid social login provider', }, - undefined + undefined, ) } } @@ -191,7 +191,7 @@ export class W3SSdk { */ verifyOtp() { this.subscribeMessage() - this.appendIframe(true, 'sso/verify-email') + this.appendIframe(true, 'social/verify-email') setTimeout(() => { if (!this.receivedResponseFromService) { @@ -200,7 +200,7 @@ export class W3SSdk { code: 155706, message: 'Network error', }, - undefined + undefined, ) } }, 1000 * 10) @@ -226,7 +226,7 @@ export class W3SSdk { setCustomSecurityQuestions( questions?: SecurityQuestion[] | null, requiredCount = 2, - securityConfirmItems?: string[] + securityConfirmItems?: string[], ): void { this.securityQuestions = questions this.securityConfirmItems = securityConfirmItems @@ -277,7 +277,7 @@ export class W3SSdk { */ setOnForgotPin( onForgotPin: () => void, - shouldCloseModalOnForgotPin = false + shouldCloseModalOnForgotPin = false, ): void { this.shouldCloseModalOnForgotPin = shouldCloseModalOnForgotPin @@ -305,7 +305,7 @@ export class W3SSdk { */ private setupInstance( configs?: Configs, - onLoginComplete?: LoginCompleteCallback + onLoginComplete?: LoginCompleteCallback, ) { if (configs?.loginConfigs?.apple && getApps().length === 0) { this.firebaseApp = initializeApp(configs.loginConfigs.apple) @@ -375,7 +375,7 @@ export class W3SSdk { code: 155706, message: 'Network error', }, - undefined + undefined, ) } }, 1000 * 10) @@ -388,7 +388,7 @@ export class W3SSdk { code: 155140, message: 'Please provide the Apple social login configurations.', }, - undefined + undefined, ) return @@ -408,7 +408,7 @@ export class W3SSdk { code: 155140, message: 'Please provide the Facebook social login configurations.', }, - undefined + undefined, ) return @@ -420,7 +420,7 @@ export class W3SSdk { this.generateOauthUrlWithParams( SocialLoginProvider.FACEBOOK, appId, - redirectUri + redirectUri, ) || {} this.saveOAuthInfo(SocialLoginProvider.FACEBOOK, state) @@ -434,7 +434,7 @@ export class W3SSdk { code: 155140, message: 'Please provide the Google social login configurations.', }, - undefined + undefined, ) return @@ -449,7 +449,7 @@ export class W3SSdk { } = this.generateOauthUrlWithParams( SocialLoginProvider.GOOGLE, clientId, - redirectUri + redirectUri, ) || {} this.saveOAuthInfo(SocialLoginProvider.GOOGLE, state, nonce) @@ -466,7 +466,7 @@ export class W3SSdk { private generateOauthUrlWithParams( provider: SocialLoginProvider, id: string, - redirectUri: string + redirectUri: string, ): | { url: string @@ -478,14 +478,14 @@ export class W3SSdk { if (provider === SocialLoginProvider.GOOGLE) { const scope = encodeURIComponent( - 'openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email' + 'openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email', ) const responseType = encodeURIComponent('id_token token') const nonce = uuidv4() return { url: `https://accounts.google.com/o/oauth2/v2/auth?client_id=${id}&redirect_uri=${encodeURIComponent( - redirectUri + redirectUri, )}&scope=${scope}&state=${state}&response_type=${responseType}&nonce=${nonce}`, state, nonce, @@ -495,7 +495,7 @@ export class W3SSdk { return { url: `https://www.facebook.com/v13.0/dialog/oauth?client_id=${id}&redirect_uri=${encodeURIComponent( - redirectUri + redirectUri, )}&scope=${scope}&state=${state}&response_type=token`, state, } @@ -506,7 +506,7 @@ export class W3SSdk { */ private async execSocialLoginStatusCheck(): Promise { const socialLoginProvider = this.window.localStorage.getItem( - 'socialLoginProvider' + 'socialLoginProvider', ) as SocialLoginProvider if (socialLoginProvider === SocialLoginProvider.APPLE) { @@ -543,7 +543,7 @@ export class W3SSdk { * @param socialLoginProvider - Social login provider. */ private handleHashLoginResponse( - socialLoginProvider: SocialLoginProvider + socialLoginProvider: SocialLoginProvider, ): void { const hashParams = new URLSearchParams(window.location.hash.slice(1)) @@ -610,13 +610,13 @@ export class W3SSdk { code: 155140, message: 'Failed to validate the idToken / accessToken', }, - undefined + undefined, ) } private verifyTokenViaService(): void { this.subscribeMessage() - this.appendIframe(false, 'sso/verify-token') + this.appendIframe(false, 'social/verify-token') setTimeout(() => { if (!this.receivedResponseFromService) { @@ -625,7 +625,7 @@ export class W3SSdk { code: 155706, message: 'Network error', }, - undefined + undefined, ) } }, 1000 * 10) @@ -640,7 +640,7 @@ export class W3SSdk { private saveOAuthInfo( provider: SocialLoginProvider, state?: string, - nonce?: string + nonce?: string, ): void { this.window.localStorage.setItem('socialLoginProvider', provider) this.window.localStorage.setItem('state', state ?? '') @@ -662,7 +662,7 @@ export class W3SSdk { code: 155140, message: 'Failed to validate the idToken / accessToken', }, - undefined + undefined, ) return false @@ -720,7 +720,7 @@ export class W3SSdk { if (event.data?.onFrameReady) { this.receivedResponseFromService = true const iframe = this.window.document.getElementById( - 'sdkIframe' + 'sdkIframe', ) as HTMLIFrameElement iframe?.contentWindow?.postMessage( { @@ -740,7 +740,7 @@ export class W3SSdk { customLinks: this.customLinks, }, deviceInfo: this.deviceInfo, - ssoVerification: { + socialVerification: { token: this.socialLoginToken, deviceToken: this.configs?.loginConfigs?.deviceToken, deviceEncryptionKey: @@ -755,13 +755,13 @@ export class W3SSdk { }, }, }, - this.serviceUrl + this.serviceUrl, ) } else if (event.data?.onForgotPin) { this.onForgotPin?.() } else if (event.data?.onComplete) { const iframe = this.window.document.getElementById( - 'sdkIframe' + 'sdkIframe', ) as HTMLIFrameElement iframe?.parentNode?.removeChild(iframe) @@ -783,7 +783,7 @@ export class W3SSdk { } else if (event.data?.onSocialLoginVerified) { void this.onLoginComplete?.( event.data.onSocialLoginVerified.error, - event.data.onSocialLoginVerified.result + event.data.onSocialLoginVerified.result, ) this.closeModal() @@ -791,7 +791,7 @@ export class W3SSdk { } else if (event.data?.onEmailLoginVerified) { void this.onLoginComplete?.( event.data.onEmailLoginVerified.error, - event.data.onEmailLoginVerified.result + event.data.onEmailLoginVerified.result, ) if ( @@ -816,7 +816,7 @@ export class W3SSdk { */ private closeModal(): void { const iframe = this.window.document.getElementById( - 'sdkIframe' + 'sdkIframe', ) as HTMLIFrameElement iframe?.parentNode?.removeChild(iframe) } diff --git a/src/types.ts b/src/types.ts index 868b6cb..8559970 100644 --- a/src/types.ts +++ b/src/types.ts @@ -139,17 +139,9 @@ export enum ErrorCode { insecurePinCode = 155704, hintsMatchAnswers = 155705, networkError = 155706, - biometricsSettingNotEnabled = 155708, - deviceNotSupportBiometrics = 155709, - biometricsKeyPermanentlyInvalidated = 155710, - biometricsUserSkip = 155711, - biometricsUserDisableForPin = 155712, - biometricsUserLockout = 155713, - biometricsUserLockoutPermanent = 155714, - biometricsUserNotAllowPermission = 155715, - biometricsInternalError = 155716, + userSecretMissing = 155717, - invalidUserSecret = 155718, + invalidUserTokenFormat = 155718, userTokenMismatch = 155719, walletIdNotFound = 156001, @@ -249,7 +241,7 @@ export interface Challenge { */ challengeId: string /** - * SSO user secret. + * Social login user secret. */ userSecret?: string } @@ -338,8 +330,8 @@ export interface SignTransactionResult extends ChallengeResult { export interface OAuthInfo { provider: SocialLoginProvider scope?: string[] - ssoUserUUID?: string - ssoUserInfo?: { + socialUserUUID?: string + socialUserInfo?: { email?: string name?: string phone?: string @@ -391,12 +383,12 @@ export type ChallengeCompleteCallback = ( | ChallengeResult | SignMessageResult | SignTransactionResult - | undefined + | undefined, ) => Promise | void export type LoginCompleteCallback = ( error: Error | undefined, - result: SocialLoginResult | EmailLoginResult | undefined + result: SocialLoginResult | EmailLoginResult | undefined, ) => Promise | void export interface PostMessageEvent extends MessageEvent { @@ -490,7 +482,7 @@ export interface SecuritySummary { question?: string } -export interface SsoConfirm { +export interface SocialEmailConfirm { title?: string headline?: string } @@ -599,7 +591,7 @@ export interface Localizations { securityIntros?: SecurityIntros securityQuestions?: SecurityQuestions securitySummary?: SecuritySummary - ssoConfirm?: SsoConfirm + socialEmailConfirm?: SocialEmailConfirm transactionRequest?: TransactionRequest contractInteraction?: ContractInteraction signatureRequest?: SignatureRequest