diff --git a/packages/@magic-sdk/provider/src/modules/auth.ts b/packages/@magic-sdk/provider/src/modules/auth.ts index 295ff4f20..2209d5a09 100644 --- a/packages/@magic-sdk/provider/src/modules/auth.ts +++ b/packages/@magic-sdk/provider/src/modules/auth.ts @@ -1,4 +1,4 @@ -import { MagicPayloadMethod, LoginWithMagicLinkConfiguration } from '@magic-sdk/types'; +import { MagicPayloadMethod, LoginWithMagicLinkConfiguration, LoginWithSmsConfiguration } from '@magic-sdk/types'; import { BaseModule } from './base-module'; import { createJsonRpcRequestPayload } from '../core/json-rpc'; import { SDKEnvironment } from '../core/sdk-environment'; @@ -25,6 +25,20 @@ export class AuthModule extends BaseModule { return this.request(requestPayload); } + /** + * Initiate an SMS login flow for a user. If successful, + * this method will return a Decenteralized ID token (with a default lifespan + * of 15 minutes) + */ + public loginWithSMS(configuration: LoginWithSmsConfiguration) { + const { phoneNumber } = configuration; + const requestPayload = createJsonRpcRequestPayload( + this.sdk.testMode ? MagicPayloadMethod.LoginWithSmsTestMode : MagicPayloadMethod.LoginWithSms, + [{ phoneNumber, showUI: true }], + ); + return this.request(requestPayload); + } + /** * Log a user in with a special one-time-use credential token. This is * currently used during magic link flows with a configured redirect to diff --git a/packages/@magic-sdk/provider/test/spec/modules/auth/loginWithSms.spec.ts b/packages/@magic-sdk/provider/test/spec/modules/auth/loginWithSms.spec.ts new file mode 100644 index 000000000..3b55c90a8 --- /dev/null +++ b/packages/@magic-sdk/provider/test/spec/modules/auth/loginWithSms.spec.ts @@ -0,0 +1,42 @@ +/* eslint-disable global-require, @typescript-eslint/no-var-requires */ + +import browserEnv from '@ikscodes/browser-env'; +import { MagicPayloadMethod } from '@magic-sdk/types'; +import { isPromiEvent } from '../../../../src/util'; +import { createMagicSDK, createMagicSDKTestMode } from '../../../factories'; + +beforeEach(() => { + browserEnv.restore(); + jest.restoreAllMocks(); +}); + +const expectedPhoneNumber = 'hey hey I am a number but jk'; + +test('Generates JSON RPC request payload with `phone` parameter', async () => { + const magic = createMagicSDK(); + magic.auth.request = jest.fn(); + + await magic.auth.loginWithSMS({ phoneNumber: expectedPhoneNumber }); + + const requestPayload = magic.auth.request.mock.calls[0][0]; + expect(requestPayload.jsonrpc).toBe('2.0'); + expect(requestPayload.method).toBe(MagicPayloadMethod.LoginWithSms); + expect(requestPayload.params).toEqual([{ phoneNumber: expectedPhoneNumber, showUI: true }]); +}); + +test('If `testMode` is enabled, testing-specific RPC method is used', async () => { + const magic = createMagicSDKTestMode(); + magic.auth.request = jest.fn(); + + await magic.auth.loginWithSMS({ phoneNumber: expectedPhoneNumber }); + + const requestPayload = magic.auth.request.mock.calls[0][0]; + expect(requestPayload.jsonrpc).toBe('2.0'); + expect(requestPayload.method).toBe(MagicPayloadMethod.LoginWithSmsTestMode); + expect(requestPayload.params).toEqual([{ phoneNumber: expectedPhoneNumber, showUI: true }]); +}); + +test('method should return a PromiEvent', () => { + const magic = createMagicSDK(); + expect(isPromiEvent(magic.auth.loginWithSMS({ email: 'blag' }))).toBeTruthy(); +}); diff --git a/packages/@magic-sdk/types/src/core/json-rpc-types.ts b/packages/@magic-sdk/types/src/core/json-rpc-types.ts index 31064d224..f48028692 100644 --- a/packages/@magic-sdk/types/src/core/json-rpc-types.ts +++ b/packages/@magic-sdk/types/src/core/json-rpc-types.ts @@ -40,6 +40,7 @@ export interface JsonRpcResponsePayload { * relayer. */ export enum MagicPayloadMethod { + LoginWithSms = 'magic_auth_login_with_sms', LoginWithMagicLink = 'magic_auth_login_with_magic_link', LoginWithCredential = 'magic_auth_login_with_credential', GetIdToken = 'magic_auth_get_id_token', @@ -48,6 +49,7 @@ export enum MagicPayloadMethod { IsLoggedIn = 'magic_auth_is_logged_in', Logout = 'magic_auth_logout', UpdateEmail = 'magic_auth_update_email', + LoginWithSmsTestMode = 'magic_auth_login_with_sms_testing_mode', LoginWithMagicLinkTestMode = 'magic_login_with_magic_link_testing_mode', LoginWithCredentialTestMode = 'magic_auth_login_with_credential_testing_mode', GetIdTokenTestMode = 'magic_auth_get_id_token_testing_mode', diff --git a/packages/@magic-sdk/types/src/modules/auth-types.ts b/packages/@magic-sdk/types/src/modules/auth-types.ts index ec69c434f..df906f031 100644 --- a/packages/@magic-sdk/types/src/modules/auth-types.ts +++ b/packages/@magic-sdk/types/src/modules/auth-types.ts @@ -19,3 +19,7 @@ export interface LoginWithMagicLinkConfiguration { */ redirectURI?: string; } + +export interface LoginWithSmsConfiguration { + phoneNumber: string; +} diff --git a/yarn.lock b/yarn.lock index 5005f60fb..44da10f1c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4118,14 +4118,14 @@ __metadata: languageName: node linkType: hard -"@magic-ext/oauth@^0.9.1, @magic-ext/oauth@workspace:packages/@magic-ext/oauth": +"@magic-ext/oauth@^0.9.2, @magic-ext/oauth@workspace:packages/@magic-ext/oauth": version: 0.0.0-use.local resolution: "@magic-ext/oauth@workspace:packages/@magic-ext/oauth" dependencies: "@magic-sdk/types": ^5.0.3 "@types/crypto-js": ~3.1.47 crypto-js: ^3.3.0 - magic-sdk: ^6.0.6 + magic-sdk: ^6.0.7 languageName: unknown linkType: soft @@ -4168,8 +4168,8 @@ __metadata: "@babel/core": ^7.9.6 "@babel/plugin-proposal-optional-chaining": ^7.9.0 "@babel/runtime": ^7.9.6 - "@magic-ext/oauth": ^0.9.1 - magic-sdk: ^6.0.6 + "@magic-ext/oauth": ^0.9.2 + magic-sdk: ^6.0.7 languageName: unknown linkType: soft @@ -13895,7 +13895,7 @@ fsevents@^1.2.7: languageName: unknown linkType: soft -"magic-sdk@^6.0.6, magic-sdk@workspace:packages/magic-sdk": +"magic-sdk@^6.0.7, magic-sdk@workspace:packages/magic-sdk": version: 0.0.0-use.local resolution: "magic-sdk@workspace:packages/magic-sdk" dependencies: