diff --git a/packages/core/src/schemas.test.ts b/packages/core/src/schemas.test.ts index 45b07c75..82bf6a0f 100644 --- a/packages/core/src/schemas.test.ts +++ b/packages/core/src/schemas.test.ts @@ -261,10 +261,9 @@ describe("createPhoneAuthNumberFormSchema", () => { const schema = createPhoneAuthNumberFormSchema(mockUI); - // Cause the schema to fail... - // TODO(ehesp): If no value is provided, the schema error is just "Required" - should this also be translated? + // 16 digits exceeds the ITU-T E.164 maximum of 15. const result = schema.safeParse({ - phoneNumber: "12345678901", + phoneNumber: "1234567890123456", }); expect(result.success).toBe(false); @@ -272,6 +271,27 @@ describe("createPhoneAuthNumberFormSchema", () => { expect(result.error?.issues[0]?.message).toBe("createPhoneAuthNumberFormSchema + invalidPhoneNumber"); }); + + it("should accept a valid 11-digit national number (e.g. China / Germany mobile)", () => { + const mockUI = createMockUI({ + locale: registerLocale("test", { + errors: { + missingPhoneNumber: "missing", + invalidPhoneNumber: "invalid", + }, + }), + }); + + const schema = createPhoneAuthNumberFormSchema(mockUI); + + // Previously rejected by the .max(10) cap. The dial code is added later by + // formatPhoneNumber, so this national number must be accepted here. + const result = schema.safeParse({ + phoneNumber: "13800138000", + }); + + expect(result.success).toBe(true); + }); }); describe("createPhoneAuthVerifyFormSchema", () => { @@ -325,6 +345,33 @@ describe("createPhoneAuthVerifyFormSchema", () => { ) ).toBe(true); }); + + it("should reject an empty verification code", () => { + const testLocale = registerLocale("test", { + errors: { + invalidVerificationCode: "createPhoneAuthVerifyFormSchema + invalidVerificationCode", + }, + }); + + const mockUI = createMockUI({ + locale: testLocale, + }); + + const schema = createPhoneAuthVerifyFormSchema(mockUI); + + const result = schema.safeParse({ + verificationId: "test-verification-id", + verificationCode: "", + }); + + expect(result.success).toBe(false); + expect(result.error).toBeDefined(); + expect( + result.error?.issues.some( + (issue) => issue.message === "createPhoneAuthVerifyFormSchema + invalidVerificationCode" + ) + ).toBe(true); + }); }); describe("createMultiFactorPhoneAuthAssertionFormSchema", () => { @@ -363,8 +410,9 @@ describe("createMultiFactorPhoneAuthAssertionFormSchema", () => { const schema = createMultiFactorPhoneAuthAssertionFormSchema(mockUI); + // 16 digits exceeds the ITU-T E.164 maximum of 15. const result = schema.safeParse({ - phoneNumber: "12345678901", + phoneNumber: "1234567890123456", }); expect(result.success).toBe(false); diff --git a/packages/core/src/schemas.ts b/packages/core/src/schemas.ts index 255b8ab6..5a013a26 100644 --- a/packages/core/src/schemas.ts +++ b/packages/core/src/schemas.ts @@ -97,7 +97,10 @@ export function createPhoneAuthNumberFormSchema(ui: FirebaseUI) { phoneNumber: z .string() .min(1, getTranslation(ui, "errors", "missingPhoneNumber")) - .max(10, getTranslation(ui, "errors", "invalidPhoneNumber")), + // National number only (dial code is added later by formatPhoneNumber). 15 is the + // ITU-T E.164 digit maximum; the previous cap of 10 rejected valid numbers such as + // 11-digit China and Germany mobiles. + .max(15, getTranslation(ui, "errors", "invalidPhoneNumber")), }); } @@ -112,9 +115,7 @@ export function createPhoneAuthNumberFormSchema(ui: FirebaseUI) { export function createPhoneAuthVerifyFormSchema(ui: FirebaseUI) { return z.object({ verificationId: z.string().min(1, getTranslation(ui, "errors", "missingVerificationId")), - verificationCode: z.string().refine((val) => !val || val.length >= 6, { - error: getTranslation(ui, "errors", "invalidVerificationCode"), - }), + verificationCode: z.string().min(6, getTranslation(ui, "errors", "invalidVerificationCode")), }); }