@opexa/portal-components 0.1.64 → 0.1.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/client/hooks/useInplaySignUpMutation.d.ts +5 -0
  2. package/dist/client/hooks/useInplaySignUpMutation.js +27 -0
  3. package/dist/client/hooks/useSessionQuery.js +11 -1
  4. package/dist/client/hooks/useSignInMutation.d.ts +2 -0
  5. package/dist/client/hooks/useSignInMutation.js +12 -6
  6. package/dist/client/services/signIn.d.ts +1 -1
  7. package/dist/client/services/signIn.js +11 -5
  8. package/dist/components/AccountInfo/AccountInfo.js +2 -2
  9. package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/OnlineBankDepositContext.d.ts +2 -2
  10. package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/useOnlineBankDeposit.d.ts +1 -1
  11. package/dist/components/KYC/KYCReminder.lazy.js +1 -1
  12. package/dist/components/SignIn/MobileNumberSignInternational.js +1 -0
  13. package/dist/components/SignIn/NameAndPasswordSignIn.js +1 -0
  14. package/dist/components/SignIn/SignIn.lazy.d.ts +3 -1
  15. package/dist/components/SignIn/SignIn.lazy.js +1 -1
  16. package/dist/components/SignUp/SignUpDefault/SignUpDefault.lazy.d.ts +1 -0
  17. package/dist/components/SignUp/SignUpDefault/SignUpDefault.lazy.js +9 -1
  18. package/dist/components/SignUp/SignUpDefault/SignUpDefaultForm.js +49 -21
  19. package/dist/constants/Endpoint.js +7 -6
  20. package/dist/constants/EnvVar.d.ts +5 -0
  21. package/dist/constants/EnvVar.js +9 -0
  22. package/dist/constants/HeaderKey.d.ts +1 -0
  23. package/dist/constants/HeaderKey.js +1 -0
  24. package/dist/constants/StorageKey.d.ts +1 -0
  25. package/dist/constants/StorageKey.js +1 -0
  26. package/dist/handlers/deleteSession.d.ts +1 -1
  27. package/dist/handlers/deleteSession.js +6 -2
  28. package/dist/handlers/getSession.js +29 -4
  29. package/dist/handlers/index.d.ts +2 -2
  30. package/dist/handlers/postSession.js +22 -4
  31. package/dist/schemas/forgotPasswordSchema.d.ts +4 -4
  32. package/dist/services/account.d.ts +47 -0
  33. package/dist/services/account.js +21 -1
  34. package/dist/services/auth.d.ts +5 -4
  35. package/dist/services/auth.js +14 -9
  36. package/dist/services/queries.d.ts +1 -0
  37. package/dist/services/queries.js +44 -0
  38. package/dist/ui/AlertDialog/AlertDialog.d.ts +121 -121
  39. package/dist/ui/AlertDialog/alertDialog.recipe.d.ts +11 -11
  40. package/dist/ui/Avatar/Avatar.d.ts +9 -9
  41. package/dist/ui/Avatar/avatar.recipe.d.ts +3 -3
  42. package/dist/ui/Badge/Badge.d.ts +12 -12
  43. package/dist/ui/Badge/badge.anatomy.d.ts +1 -1
  44. package/dist/ui/Badge/badge.recipe.d.ts +3 -3
  45. package/dist/ui/Carousel/Carousel.d.ts +72 -72
  46. package/dist/ui/Carousel/carousel.recipe.d.ts +8 -8
  47. package/dist/ui/Checkbox/Checkbox.d.ts +23 -23
  48. package/dist/ui/Checkbox/checkbox.recipe.d.ts +3 -3
  49. package/dist/ui/Clipboard/Clipboard.d.ts +18 -18
  50. package/dist/ui/Clipboard/clipboard.recipe.d.ts +3 -3
  51. package/dist/ui/Collapsible/Collapsible.d.ts +20 -20
  52. package/dist/ui/Collapsible/collapsible.recipe.d.ts +5 -5
  53. package/dist/ui/Combobox/Combobox.d.ts +42 -42
  54. package/dist/ui/Combobox/combobox.recipe.d.ts +3 -3
  55. package/dist/ui/DatePicker/DatePicker.d.ts +72 -72
  56. package/dist/ui/DatePicker/datePicker.recipe.d.ts +3 -3
  57. package/dist/ui/Dialog/Dialog.d.ts +33 -33
  58. package/dist/ui/Dialog/dialog.recipe.d.ts +3 -3
  59. package/dist/ui/Drawer/Drawer.d.ts +33 -33
  60. package/dist/ui/Drawer/drawer.recipe.d.ts +3 -3
  61. package/dist/ui/Field/Field.d.ts +21 -21
  62. package/dist/ui/Field/field.recipe.d.ts +3 -3
  63. package/dist/ui/Menu/Menu.d.ts +144 -144
  64. package/dist/ui/Menu/menu.recipe.d.ts +8 -8
  65. package/dist/ui/NumberInput/NumberInput.d.ts +24 -24
  66. package/dist/ui/NumberInput/numberInput.recipe.d.ts +3 -3
  67. package/dist/ui/PasswordInput/PasswordInput.d.ts +18 -18
  68. package/dist/ui/PasswordInput/passwordInput.recipe.d.ts +3 -3
  69. package/dist/ui/PinInput/PinInput.d.ts +12 -12
  70. package/dist/ui/PinInput/pinInput.recipe.d.ts +3 -3
  71. package/dist/ui/Popover/Popover.d.ts +88 -88
  72. package/dist/ui/Popover/popover.recipe.d.ts +8 -8
  73. package/dist/ui/Progress/Progress.d.ts +27 -27
  74. package/dist/ui/Progress/progress.recipe.d.ts +3 -3
  75. package/dist/ui/QrCode/QrCode.d.ts +25 -25
  76. package/dist/ui/QrCode/qrCode.recipe.d.ts +5 -5
  77. package/dist/ui/SegmentGroup/SegmentGroup.d.ts +18 -18
  78. package/dist/ui/SegmentGroup/segmentGroup.recipe.d.ts +3 -3
  79. package/dist/ui/Select/Select.d.ts +45 -45
  80. package/dist/ui/Select/select.recipe.d.ts +3 -3
  81. package/dist/ui/Table/Table.d.ts +21 -21
  82. package/dist/ui/Table/table.anatomy.d.ts +1 -1
  83. package/dist/ui/Table/table.recipe.d.ts +3 -3
  84. package/dist/ui/Tabs/Tabs.d.ts +15 -15
  85. package/dist/ui/Tabs/tabs.recipe.d.ts +3 -3
  86. package/package.json +2 -1
@@ -0,0 +1,5 @@
1
+ import { type RegisterMemberAccountByMobileNumberInplayInput } from '../../services/account';
2
+ import type { Mutation } from '../../types';
3
+ export interface InplaySignUpMutationInput extends Omit<RegisterMemberAccountByMobileNumberInplayInput, 'cellxpertCxd'> {
4
+ }
5
+ export declare const useInplaySignUpMutation: Mutation<void, InplaySignUpMutationInput>;
@@ -0,0 +1,27 @@
1
+ import { useMutation } from '@tanstack/react-query';
2
+ import { registerMemberAccountByMobileNumberInplay, } from '../../services/account.js';
3
+ import { getSignUpMutationKey } from '../../utils/mutationKeys.js';
4
+ import { getSession } from '../services/getSession.js';
5
+ import { useCellxpertCxd } from './useCellxpertCxd.js';
6
+ export const useInplaySignUpMutation = (config) => {
7
+ const [cellxpertCxd] = useCellxpertCxd();
8
+ return useMutation({
9
+ ...config,
10
+ mutationKey: getSignUpMutationKey(),
11
+ mutationFn: async (input) => {
12
+ const session = await getSession();
13
+ return await registerMemberAccountByMobileNumberInplay({
14
+ ...input,
15
+ ...(cellxpertCxd && {
16
+ cellxpertCxd: cellxpertCxd.value,
17
+ }),
18
+ }, {
19
+ headers: {
20
+ ...(session.domain && {
21
+ Domain: session.domain,
22
+ }),
23
+ },
24
+ });
25
+ },
26
+ });
27
+ };
@@ -1,6 +1,8 @@
1
1
  import { useQuery } from '@tanstack/react-query';
2
+ import { FINGERPRINT_HEADER_KEY } from '../../constants/index.js';
2
3
  import { getSessionQueryKey } from '../../utils/queryKeys.js';
3
4
  import { getSession } from '../services/getSession.js';
5
+ import { getFingerprint } from './useSignInMutation.js';
4
6
  export const useSessionQuery = (config) => {
5
7
  return useQuery({
6
8
  gcTime: 1000 * 2,
@@ -8,7 +10,15 @@ export const useSessionQuery = (config) => {
8
10
  ...config,
9
11
  queryKey: getSessionQueryKey(),
10
12
  queryFn: async ({ signal }) => {
11
- return await getSession({ signal });
13
+ const fingerprint = await getFingerprint();
14
+ return await getSession({
15
+ signal,
16
+ headers: {
17
+ ...(fingerprint && {
18
+ [FINGERPRINT_HEADER_KEY]: fingerprint,
19
+ }),
20
+ },
21
+ });
12
22
  },
13
23
  });
14
24
  };
@@ -4,6 +4,8 @@ import type { Authenticator, MutationConfig } from '../../types';
4
4
  import { type SignInInput } from '../services/signIn';
5
5
  export interface UseSignInMutationOptions extends MutationConfig<Authenticator | null, SignInInput> {
6
6
  versionSession?: VersionSession;
7
+ authApiBaseUrl?: string;
7
8
  version?: ApiVersion;
8
9
  }
9
10
  export declare const useSignInMutation: (options?: UseSignInMutationOptions) => UseMutationResult<Authenticator | null, Error, SignInInput>;
11
+ export declare function getFingerprint(): Promise<string | null>;
@@ -8,19 +8,25 @@ import { getSignInMutationKey } from '../../utils/mutationKeys.js';
8
8
  import { getSessionQueryKey } from '../../utils/queryKeys.js';
9
9
  import { getSession } from '../services/getSession.js';
10
10
  import { signIn } from '../services/signIn.js';
11
+ import { useFeatureFlag } from './useFeatureFlag.js';
11
12
  import { useRecaptcha } from './useRecaptcha.js';
12
13
  export const useSignInMutation = (options) => {
13
14
  const queryClient = getQueryClient();
14
15
  const { executeRecaptcha, isGoogleFraudDefense } = useRecaptcha();
15
- const { versionSession, version = 1, ...config } = options ?? {};
16
+ const { enabled: featureFlagEnabled } = useFeatureFlag();
17
+ const { versionSession, version = 1, authApiBaseUrl, ...config } = options ?? {};
16
18
  return useMutation({
17
19
  ...config,
18
20
  mutationKey: getSignInMutationKey(),
19
21
  mutationFn: async (input) => {
20
22
  const session = await getSession();
21
23
  const token = await executeRecaptcha('submit');
22
- const isInplayEligible = input.type === 'NAME_AND_PASSWORD' || input.type === 'MOBILE_NUMBER';
23
- const fingerprint = (versionSession === 'Inplay' || version !== 1) && isInplayEligible
24
+ const isInplay = versionSession === 'Inplay' &&
25
+ (input.type === 'NAME_AND_PASSWORD' ||
26
+ (input.type === 'MOBILE_NUMBER' && featureFlagEnabled));
27
+ const fingerprint = (input.type === 'NAME_AND_PASSWORD' &&
28
+ (versionSession === 'Inplay' || version !== 1)) ||
29
+ (input.type === 'MOBILE_NUMBER' && isInplay)
24
30
  ? await getFingerprint()
25
31
  : null;
26
32
  const recaptchaHeaderKey = isGoogleFraudDefense
@@ -41,8 +47,8 @@ export const useSignInMutation = (options) => {
41
47
  ? { Channel: 'ANDROID' }
42
48
  : { Channel: 'IOS' }),
43
49
  },
44
- }, versionSession, version);
45
- const authenticator = versionSession === 'Inplay' && isInplayEligible
50
+ }, versionSession, version, authApiBaseUrl, featureFlagEnabled);
51
+ const authenticator = isInplay
46
52
  ? await pollSignIn(signInOnce)
47
53
  : await signInOnce();
48
54
  if (!authenticator) {
@@ -82,7 +88,7 @@ async function pollSignIn(signInOnce) {
82
88
  return result.authenticator;
83
89
  }
84
90
  let thumbmark_instance;
85
- async function getFingerprint() {
91
+ export async function getFingerprint() {
86
92
  if (typeof window === 'undefined')
87
93
  return null;
88
94
  if (!thumbmark_instance) {
@@ -2,4 +2,4 @@ import type { ApiVersion, CreateSessionInput, VersionSession } from '../../servi
2
2
  import { type HttpRequestOptions } from '../../services/httpRequest';
3
3
  import type { Authenticator } from '../../types';
4
4
  export type SignInInput = CreateSessionInput;
5
- export declare function signIn(input: SignInInput, options?: HttpRequestOptions, versionSession?: VersionSession, version?: ApiVersion): Promise<Authenticator | null>;
5
+ export declare function signIn(input: SignInInput, options?: HttpRequestOptions, versionSession?: VersionSession, version?: ApiVersion, authApiBaseUrl?: string, isInplayMobileEnabled?: boolean): Promise<Authenticator | null>;
@@ -1,13 +1,19 @@
1
1
  import { Capacitor } from '@capacitor/core';
2
- import { API_VERSION_HEADER_KEY, PLATFORM_WEB_HEADER_KEY, SESSION_VERSION_HEADER_KEY, } from '../../constants/index.js';
2
+ import { API_VERSION_HEADER_KEY, AUTH_API_BASE_URL_HEADER_KEY, SESSION_VERSION_HEADER_KEY, } from '../../constants/index.js';
3
3
  import { httpRequest, } from '../../services/httpRequest.js';
4
4
  const platform = Capacitor.getPlatform();
5
- export async function signIn(input, options, versionSession = 'default', version = 1) {
5
+ export async function signIn(input, options, versionSession = 'default', version = 1, authApiBaseUrl, isInplayMobileEnabled = false) {
6
6
  const headers = new Headers(options?.headers);
7
- headers.set(SESSION_VERSION_HEADER_KEY, versionSession);
7
+ const effectiveVersionSession = input.type === 'MOBILE_NUMBER' && !isInplayMobileEnabled
8
+ ? 'default'
9
+ : versionSession;
10
+ headers.set(SESSION_VERSION_HEADER_KEY, effectiveVersionSession);
8
11
  headers.set(API_VERSION_HEADER_KEY, String(version));
9
- if (version === 4 && platform === 'web') {
10
- headers.set(PLATFORM_WEB_HEADER_KEY, 'true');
12
+ // if (version === 4 && platform === 'web') {
13
+ // headers.set(PLATFORM_WEB_HEADER_KEY, 'true');
14
+ // }
15
+ if (authApiBaseUrl) {
16
+ headers.set(AUTH_API_BASE_URL_HEADER_KEY, authApiBaseUrl);
11
17
  }
12
18
  const res = await httpRequest.json('/api/sessions', {
13
19
  ...options,
@@ -12,10 +12,9 @@ import { twMerge } from 'tailwind-merge';
12
12
  import { z } from 'zod';
13
13
  import { useAccountQuery } from '../../client/hooks/useAccountQuery.js';
14
14
  import { useDisclosure } from '../../client/hooks/useDisclosure.js';
15
- import { useLocaleInfo } from '../../client/hooks/useLocaleInfo.js';
16
- import { getLocale, extractPhoneCode, } from '../../utils/countries/getLocaleInfo.js';
17
15
  import { useFacebookClientQuery } from '../../client/hooks/useFacebookClientQuery.js';
18
16
  import { useGoogleClientIdQuery } from '../../client/hooks/useGoogleClientIdQuery.js';
17
+ import { useLocaleInfo } from '../../client/hooks/useLocaleInfo.js';
19
18
  import { useMemberVerificationQuery } from '../../client/hooks/useMemberVerificationQuery.js';
20
19
  import { useMobileNumberParser } from '../../client/hooks/useMobileNumberParser.js';
21
20
  import { useProfileCompletionQuery } from '../../client/hooks/useProfileCompletionQuery.js';
@@ -38,6 +37,7 @@ import { Dialog } from '../../ui/Dialog/index.js';
38
37
  import { Field } from '../../ui/Field/index.js';
39
38
  import { IconButton } from '../../ui/IconButton/index.js';
40
39
  import { Portal } from '../../ui/Portal/index.js';
40
+ import { extractPhoneCode, getLocale, } from '../../utils/countries/getLocaleInfo.js';
41
41
  import { getQueryClient } from '../../utils/getQueryClient.js';
42
42
  import { getAccountQueryKey, getProfileCompletionQueryKey, } from '../../utils/queryKeys.js';
43
43
  const accountSchema = z.object({
@@ -1,6 +1,6 @@
1
1
  export declare const OnlineBankDepositContext: (props: {
2
2
  value: {
3
- view: "vca" | "form";
3
+ view: "form" | "vca";
4
4
  status: "waiting" | "failed" | "processing" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
5
5
  verify: () => void;
6
6
  reset: () => void;
@@ -13,7 +13,7 @@ export declare const OnlineBankDepositContext: (props: {
13
13
  } & {
14
14
  children?: import("react").ReactNode | undefined;
15
15
  }) => React.ReactNode, useOnlineBankDepositContext: () => {
16
- view: "vca" | "form";
16
+ view: "form" | "vca";
17
17
  status: "waiting" | "failed" | "processing" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
18
18
  verify: () => void;
19
19
  reset: () => void;
@@ -1,7 +1,7 @@
1
1
  import type { Deposit } from '../../../../types';
2
2
  export type UseOnlineBankDepositReturn = ReturnType<typeof useOnlineBankDeposit>;
3
3
  export declare function useOnlineBankDeposit(): {
4
- view: "vca" | "form";
4
+ view: "form" | "vca";
5
5
  status: "waiting" | "failed" | "processing" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
6
6
  verify: () => void;
7
7
  reset: () => void;
@@ -11,7 +11,6 @@ import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
11
11
  import { useSessionQuery } from '../../client/hooks/useSessionQuery.js';
12
12
  import { useSignOutMutation } from '../../client/hooks/useSignOutMutation.js';
13
13
  import { getSession } from '../../client/services/getSession.js';
14
- import { clearLocalStorageOnLogout } from '../../utils/clear-local-storage-on-logout.js';
15
14
  import { FileCheck02Icon } from '../../icons/FileCheck02Icon.js';
16
15
  import { XIcon } from '../../icons/XIcon.js';
17
16
  import pagcorLogo from '../../images/pagcor.png';
@@ -20,6 +19,7 @@ import { unregisterFCMDevice } from '../../services/trigger.js';
20
19
  import { Button } from '../../ui/Button/index.js';
21
20
  import { Dialog } from '../../ui/Dialog/index.js';
22
21
  import { Portal } from '../../ui/Portal/index.js';
22
+ import { clearLocalStorageOnLogout } from '../../utils/clear-local-storage-on-logout.js';
23
23
  import { getQueryClient } from '../../utils/getQueryClient.js';
24
24
  import { getSessionQueryKey } from '../../utils/queryKeys.js';
25
25
  export function KYCReminder({ enablePendingKycReminder = false, ...props }) {
@@ -81,6 +81,7 @@ export function MobileNumberSignInInternational() {
81
81
  termsOfUse: ctx.termsOfUse,
82
82
  })));
83
83
  const signInMutation = useSignInMutation({
84
+ authApiBaseUrl: signInProps.authApiBaseUrl,
84
85
  versionSession: signInProps.versionSession,
85
86
  version: signInProps.version,
86
87
  onSuccess: async () => {
@@ -55,6 +55,7 @@ export function NameAndPasswordSignIn() {
55
55
  })));
56
56
  const [formType, setFormType] = useState('NAME_AND_PASSWORD');
57
57
  const signInMutation = useSignInMutation({
58
+ authApiBaseUrl: signInProps.authApiBaseUrl,
58
59
  versionSession: signInProps.versionSession,
59
60
  version: signInProps.version,
60
61
  onSuccess: async (authenticator) => {
@@ -25,10 +25,12 @@ export interface SignInProps extends UseSignInProps {
25
25
  shouldShowResponsibleGamingReminder?: boolean;
26
26
  shouldShowDisclaimer?: boolean;
27
27
  variant?: 'crazywin' | 'happybingo';
28
+ authApiBaseUrl?: string;
28
29
  /**
29
30
  * Selects which auth session endpoint the sign-in flow targets.
30
31
  * - `default` (default): `${AUTH_ENDPOINT}/sessions`
31
- * - `Inplay`: `${AUTH_ENDPOINT}/v3/inplay/sessions`
32
+ * - `Inplay`: `${AUTH_ENDPOINT}/v3/inplay/sessions`, or `/v4/inplay/sessions`
33
+ * when `version` is `4`
32
34
  */
33
35
  versionSession?: VersionSession;
34
36
  /**
@@ -9,8 +9,8 @@ import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
9
9
  import { XIcon } from '../../icons/XIcon.js';
10
10
  import { Dialog } from '../../ui/Dialog/index.js';
11
11
  import { Portal } from '../../ui/Portal/index.js';
12
- import { MigrateLoadingDialog } from '../Migrate/MigrateLoadingDialog.js';
13
12
  import { getSignInMutationKey } from '../../utils/mutationKeys.js';
13
+ import { MigrateLoadingDialog } from '../Migrate/MigrateLoadingDialog.js';
14
14
  import { SignInForm as CWSignInForm } from './CrazyWin/SignInForm.js';
15
15
  import { SignInForm as HBSignInForm } from './HappyBingo/SignInForm.js';
16
16
  import { SignInPropsProvider, SignInProvider } from './SignInContext.js';
@@ -13,6 +13,7 @@ export interface SignUpDefaultProps {
13
13
  logo: ImageProps['src'];
14
14
  basicSignUp?: boolean;
15
15
  branches?: Branch[];
16
+ featureFlagBranches?: Branch[];
16
17
  enabledCountries?: CountryCode[];
17
18
  termsAndConditionsUrl?: string;
18
19
  responsibleGamingUrl?: string;
@@ -4,6 +4,7 @@ import Image, {} from 'next/image';
4
4
  import { Suspense } from 'react';
5
5
  import { twMerge } from 'tailwind-merge';
6
6
  import { useShallow } from 'zustand/shallow';
7
+ import { useFeatureFlag } from '../../../client/hooks/useFeatureFlag.js';
7
8
  import { useGlobalStore } from '../../../client/hooks/useGlobalStore.js';
8
9
  import { XIcon } from '../../../icons/XIcon.js';
9
10
  import { Dialog } from '../../../ui/Dialog/index.js';
@@ -12,12 +13,19 @@ import { SignUpDefaultPropsProvider } from './SignUpDefaultContext.js';
12
13
  import { SignUpDefaultForm } from './SignUpDefaultForm.js';
13
14
  import { SignUpDefaultFormInternational } from './SignUpDefaultFormInternational.js';
14
15
  export function SignUpDefault(props) {
16
+ const { enabled: featureFlagEnabled } = useFeatureFlag();
15
17
  const signUpStore = useGlobalStore(useShallow((ctx) => ctx.signUp));
16
18
  const globalStore = useGlobalStore(useShallow((ctx) => ({
17
19
  termsAndConditions: ctx.termsAndConditions,
18
20
  responsibleGaming: ctx.responsibleGaming,
19
21
  })));
20
- return (_jsx(SignUpDefaultPropsProvider, { value: props, children: _jsx(Dialog.Root, { open: signUpStore.open, onOpenChange: (details) => {
22
+ return (_jsx(SignUpDefaultPropsProvider, { value: {
23
+ ...props,
24
+ branches: [
25
+ ...(props.branches ?? []),
26
+ ...(featureFlagEnabled ? (props.featureFlagBranches ?? []) : []),
27
+ ],
28
+ }, children: _jsx(Dialog.Root, { open: signUpStore.open, onOpenChange: (details) => {
21
29
  signUpStore.setOpen(details.open);
22
30
  }, lazyMount: true, unmountOnExit: true, closeOnEscape: false, closeOnInteractOutside: false, onExitComplete: () => {
23
31
  // Reset checkbox state when dialog closes
@@ -14,6 +14,7 @@ import { useShallow } from 'zustand/shallow';
14
14
  import { useCooldown } from '../../../client/hooks/useCooldown.js';
15
15
  import { useFeatureFlag } from '../../../client/hooks/useFeatureFlag.js';
16
16
  import { useGlobalStore } from '../../../client/hooks/useGlobalStore.js';
17
+ import { useInplaySignUpMutation } from '../../../client/hooks/useInplaySignUpMutation.js';
17
18
  import { useLocaleInfo } from '../../../client/hooks/useLocaleInfo.js';
18
19
  import { useMobileNumberParser } from '../../../client/hooks/useMobileNumberParser.js';
19
20
  import { useSendVerificationCodeMutation } from '../../../client/hooks/useSendVerificationCodeMutation.js';
@@ -27,7 +28,6 @@ import { HelpCircleIcon } from '../../../icons/HelpCircleIcon.js';
27
28
  import pagcorLogo from '../../../images/pagcor-round-icon.png';
28
29
  import responsibleGamingLogo from '../../../images/responsible-gaming-gold.png';
29
30
  import { ObjectType } from '../../../services/ObjectType.js';
30
- import { checkInplayMemberExists } from '../../../services/auth.js';
31
31
  import { Button } from '../../../ui/Button/index.js';
32
32
  import { Checkbox } from '../../../ui/Checkbox/index.js';
33
33
  import { Field } from '../../../ui/Field/index.js';
@@ -69,7 +69,10 @@ export function SignUpDefaultForm() {
69
69
  })));
70
70
  const search = useSearchParams();
71
71
  const signUpMutation = useSignUpMutation();
72
- const signInMutation = useSignInMutation();
72
+ const inplaySignUpMutation = useInplaySignUpMutation();
73
+ const signInMutation = useSignInMutation({
74
+ versionSession: signUpProps.versionSession,
75
+ });
73
76
  const sendVerificationCodeMutation = useSendVerificationCodeMutation();
74
77
  const featureFlag = useFeatureFlag();
75
78
  const localeInfo = useLocaleInfo();
@@ -246,21 +249,6 @@ export function SignUpDefaultForm() {
246
249
  }
247
250
  return (_jsxs(_Fragment, { children: [step === 1 && (_jsxs(_Fragment, { children: [_jsx("h2", { className: "mt-xl text-center font-semibold text-lg", children: "Create an account" }), _jsx("p", { className: "mt-xs text-center text-sm text-text-secondary-700", children: "Register instantly and start playing!" }), _jsxs("form", { className: "mt-3xl", autoComplete: "off", onSubmit: step1Form.handleSubmit(async (data) => {
248
251
  try {
249
- if (signUpProps.versionSession === 'Inplay' &&
250
- featureFlag.enabled) {
251
- const exists = await checkInplayMemberExists(mobileNumberParser.format(data.mobileNumber));
252
- if (exists) {
253
- toaster.warning({
254
- description: 'This mobile number is already registered. Please try to log in.',
255
- });
256
- globalStore.setPrefillMobileNumber(data.mobileNumber);
257
- globalStore.setPendingType('MOBILE_NUMBER');
258
- globalStore.signUp.setOpen(false);
259
- globalStore.signIn.setOpen(true);
260
- step1Form.reset();
261
- return;
262
- }
263
- }
264
252
  await sendVerificationCodeMutation.mutateAsync({
265
253
  channel: 'SMS',
266
254
  recipient: mobileNumberParser.format(data.mobileNumber),
@@ -331,10 +319,9 @@ export function SignUpDefaultForm() {
331
319
  const { mobileNumber } = step1Form.getValues();
332
320
  const birthdayValue = step1Form.getValues('birthDay');
333
321
  try {
334
- await signUpMutation.mutateAsync({
322
+ const signUpInput = {
335
323
  id,
336
324
  mobileNumber: mobileNumberParser.format(mobileNumber),
337
- verificationCode: verificationCode.join(''),
338
325
  ...(!signUpProps.basicSignUp && {
339
326
  realName: [
340
327
  step1Form.getValues('firstName'),
@@ -344,7 +331,7 @@ export function SignUpDefaultForm() {
344
331
  .filter(Boolean)
345
332
  .join(' '),
346
333
  ...(!!birthdayValue && {
347
- birthDay: format(birthdayValue, 'yyyy-MM-dd'),
334
+ dateOfBirth: format(birthdayValue, 'yyyy-MM-dd'),
348
335
  }),
349
336
  ...(signUpProps?.branches &&
350
337
  signUpProps.branches.length > 0 && {
@@ -358,6 +345,44 @@ export function SignUpDefaultForm() {
358
345
  }),
359
346
  referralCode: search.get('referralCode') ?? undefined,
360
347
  agentCode,
348
+ };
349
+ if (signUpProps.versionSession === 'Inplay' &&
350
+ featureFlag.enabled) {
351
+ await inplaySignUpMutation.mutateAsync({
352
+ ...signUpInput,
353
+ mobileNumberVerificationCode: verificationCode.join(''),
354
+ });
355
+ const name = mobileNumberParser.format(mobileNumber);
356
+ const password = `${name}${id}`;
357
+ try {
358
+ await signInMutation.mutateAsync({
359
+ type: 'NAME_AND_PASSWORD',
360
+ name,
361
+ password,
362
+ });
363
+ }
364
+ catch {
365
+ globalStore.setPrefillMobileNumber(name);
366
+ globalStore.setPendingType('MOBILE_NUMBER');
367
+ globalStore.signUp.setOpen(false);
368
+ globalStore.signIn.setOpen(true);
369
+ step1Form.reset();
370
+ step2Form.reset();
371
+ setStep(1);
372
+ return;
373
+ }
374
+ globalStore.signUp.setOpen(false);
375
+ globalStore.setFirstTimeSignUp(true);
376
+ step1Form.reset();
377
+ step2Form.reset();
378
+ setStep(1);
379
+ return;
380
+ }
381
+ const { dateOfBirth, ...legacySignUpInput } = signUpInput;
382
+ await signUpMutation.mutateAsync({
383
+ ...legacySignUpInput,
384
+ birthDay: dateOfBirth,
385
+ verificationCode: verificationCode.join(''),
361
386
  });
362
387
  const name = mobileNumberParser.format(mobileNumber);
363
388
  const password = `${name}${id}`;
@@ -391,7 +416,10 @@ export function SignUpDefaultForm() {
391
416
  }
392
417
  catch (error) {
393
418
  if (error instanceof Error &&
394
- error.name === 'MemberAccountAlreadyExistsError') {
419
+ (error.name === 'MemberAccountAlreadyExistsError' ||
420
+ (signUpProps.versionSession === 'Inplay' &&
421
+ featureFlag.enabled &&
422
+ error.name === 'MobileNumberNotAvailableError'))) {
395
423
  toaster.warning({
396
424
  description: 'This mobile number is already registered. Please try to log in.',
397
425
  });
@@ -1,4 +1,4 @@
1
- import { ENVIRONMENT } from './EnvVar.js';
1
+ import { AUTH_API_BASE_URL, ENVIRONMENT } from './EnvVar.js';
2
2
  export const ACCOUNT_GRAPHQL_ENDPOINT = {
3
3
  development: 'https://account.development.opexa.io/graphql',
4
4
  staging: 'https://account.staging.atalos.io/graphql',
@@ -34,11 +34,12 @@ export const WALLET_GRAPHQL_ENDPOINT = {
34
34
  staging: 'https://wallet.staging.atalos.io/graphql',
35
35
  production: 'https://wallet.opexa.io/graphql',
36
36
  }[ENVIRONMENT];
37
- export const AUTH_ENDPOINT = {
38
- development: 'https://auth.development.opexa.io',
39
- staging: 'https://auth.staging.atalos.io',
40
- production: 'https://auth.opexa.io',
41
- }[ENVIRONMENT];
37
+ export const AUTH_ENDPOINT = AUTH_API_BASE_URL ||
38
+ {
39
+ development: 'https://auth.development.opexa.io',
40
+ staging: 'https://auth.staging.atalos.io',
41
+ production: 'https://auth.opexa.io',
42
+ }[ENVIRONMENT];
42
43
  export const CMS_PORTAL_ENDPOINT = {
43
44
  development: 'https://portal-api.opexacms.io',
44
45
  staging: 'https://portal-api.staging.opexacms.io',
@@ -2,4 +2,9 @@ export declare const SITE_ID: string;
2
2
  export declare const PLATFORM_ID: string;
3
3
  export declare const PLATFORM_CODE: string;
4
4
  export declare const ENVIRONMENT: "production" | "staging" | "development";
5
+ /**
6
+ * Overrides the auth service base URL for all environments, taking
7
+ * precedence over the per-environment default in `AUTH_ENDPOINT`.
8
+ */
9
+ export declare const AUTH_API_BASE_URL: string | undefined;
5
10
  export declare const INTERNALS__REPORT_WEB_VITALS: boolean;
@@ -18,6 +18,15 @@ export const ENVIRONMENT = z
18
18
  .enum(['production', 'staging', 'development'])
19
19
  .catch('development')
20
20
  .parse(process.env.NEXT_PUBLIC_ENVIRONMENT);
21
+ /**
22
+ * Overrides the auth service base URL for all environments, taking
23
+ * precedence over the per-environment default in `AUTH_ENDPOINT`.
24
+ */
25
+ export const AUTH_API_BASE_URL = z
26
+ .string()
27
+ .trim()
28
+ .optional()
29
+ .parse(process.env.NEXT_PUBLIC_AUTH_API_BASE_URL);
21
30
  export const INTERNALS__REPORT_WEB_VITALS = z
22
31
  .any()
23
32
  .transform(Boolean)
@@ -2,6 +2,7 @@ export declare const RECAPTCHA_HEADER_KEY: string;
2
2
  export declare const TEST_PASS_HEADER_KEY: string;
3
3
  export declare const DOMAIN_HEADER_KEY: string;
4
4
  export declare const SESSION_VERSION_HEADER_KEY: string;
5
+ export declare const AUTH_API_BASE_URL_HEADER_KEY: string;
5
6
  export declare const API_VERSION_HEADER_KEY: string;
6
7
  export declare const PLATFORM_WEB_HEADER_KEY: string;
7
8
  export declare const FINGERPRINT_HEADER_KEY: string;
@@ -2,6 +2,7 @@ export const RECAPTCHA_HEADER_KEY = 'Google-Recaptcha-Response';
2
2
  export const TEST_PASS_HEADER_KEY = 'Test-Pass';
3
3
  export const DOMAIN_HEADER_KEY = 'Domain';
4
4
  export const SESSION_VERSION_HEADER_KEY = 'X-Session-Version';
5
+ export const AUTH_API_BASE_URL_HEADER_KEY = 'X-Auth-Api-Base-Url';
5
6
  export const API_VERSION_HEADER_KEY = 'X-Api-Version';
6
7
  export const PLATFORM_WEB_HEADER_KEY = 'X-Platform-Web';
7
8
  export const FINGERPRINT_HEADER_KEY = 'Fingerprint';
@@ -1,3 +1,4 @@
1
+ export declare const AUTH_CONFIG_COOKIE_NAME: string;
1
2
  export declare const ACCESS_TOKEN_COOKIE_NAME: string;
2
3
  export declare const REFRESH_TOKEN_COOKIE_NAME: string;
3
4
  export declare const DOMAIN_COOKIE_NAME: string;
@@ -1,3 +1,4 @@
1
+ export const AUTH_CONFIG_COOKIE_NAME = 'WebPortalAuthConfig';
1
2
  export const ACCESS_TOKEN_COOKIE_NAME = 'WebPortalAuthAccessToken';
2
3
  export const REFRESH_TOKEN_COOKIE_NAME = 'WebPortalAuthRefreshToken';
3
4
  export const DOMAIN_COOKIE_NAME = 'WebPortalDomain';
@@ -1,4 +1,4 @@
1
- import { NextResponse, type NextRequest } from 'next/server';
1
+ import { type NextRequest, NextResponse } from 'next/server';
2
2
  export declare function deleteSession(request: NextRequest): Promise<NextResponse<{
3
3
  ok: true;
4
4
  data?: never;
@@ -1,14 +1,18 @@
1
1
  import { NextResponse } from 'next/server';
2
- import { ACCESS_TOKEN_COOKIE_NAME, REFRESH_TOKEN_COOKIE_NAME, } from '../constants/index.js';
2
+ import { ACCESS_TOKEN_COOKIE_NAME, AUTH_CONFIG_COOKIE_NAME, REFRESH_TOKEN_COOKIE_NAME, } from '../constants/index.js';
3
3
  import { destroySession } from '../services/auth.js';
4
4
  export async function deleteSession(request) {
5
5
  const accessToken = request.cookies.get(ACCESS_TOKEN_COOKIE_NAME)?.value;
6
+ const authConfig = JSON.parse(request.cookies.get(AUTH_CONFIG_COOKIE_NAME)?.value ?? '{}');
7
+ const authApiBaseUrl = authConfig.apiBaseUrl;
8
+ console.log('[DESTROY SESSION]');
9
+ console.log({ authApiBaseUrl });
6
10
  if (accessToken) {
7
11
  await destroySession({
8
12
  headers: {
9
13
  Authorization: `Bearer ${accessToken}`,
10
14
  },
11
- });
15
+ }, authApiBaseUrl);
12
16
  }
13
17
  const response = NextResponse.json({
14
18
  ok: true,
@@ -1,11 +1,21 @@
1
- import { addMinutes } from 'date-fns';
1
+ import { addDays, addMinutes, subMinutes } from 'date-fns';
2
2
  import { NextResponse } from 'next/server';
3
- import { ACCESS_TOKEN_COOKIE_NAME, BTAG_COOKIE_NAME, DOMAIN_COOKIE_NAME, REFRESH_TOKEN_COOKIE_NAME, } from '../constants/index.js';
3
+ import { ACCESS_TOKEN_COOKIE_NAME, AUTH_CONFIG_COOKIE_NAME, BTAG_COOKIE_NAME, DOMAIN_COOKIE_NAME, FINGERPRINT_HEADER_KEY, REFRESH_TOKEN_COOKIE_NAME, } from '../constants/index.js';
4
4
  import { refreshSession } from '../services/auth.js';
5
5
  export async function getSession(request) {
6
6
  const accessToken = request.cookies.get(ACCESS_TOKEN_COOKIE_NAME)?.value;
7
+ const authConfig = JSON.parse(request.cookies.get(AUTH_CONFIG_COOKIE_NAME)?.value ?? '{}');
8
+ const authVersion = authConfig.version;
9
+ const authApiBaseUrl = authConfig.apiBaseUrl;
10
+ const fingerprint = request.headers.get(FINGERPRINT_HEADER_KEY);
11
+ console.log('[GET SESSION]');
12
+ console.log({
13
+ authVersion,
14
+ authApiBaseUrl,
15
+ fingerprint,
16
+ });
7
17
  let isAccessTokenValid = true;
8
- if (accessToken) {
18
+ if (accessToken && authVersion !== 4) {
9
19
  try {
10
20
  const payload = accessToken.split('.')[1];
11
21
  const decoded = JSON.parse(Buffer.from(payload, 'base64').toString('utf8'));
@@ -17,6 +27,9 @@ export async function getSession(request) {
17
27
  isAccessTokenValid = false;
18
28
  }
19
29
  }
30
+ if (authVersion === 4 && !accessToken) {
31
+ isAccessTokenValid = false;
32
+ }
20
33
  const refreshToken = request.cookies.get(REFRESH_TOKEN_COOKIE_NAME)?.value;
21
34
  const domain = request.cookies.get(DOMAIN_COOKIE_NAME)?.value;
22
35
  const btag = request.cookies.get(BTAG_COOKIE_NAME)?.value;
@@ -31,6 +44,7 @@ export async function getSession(request) {
31
44
  });
32
45
  response.cookies.delete(ACCESS_TOKEN_COOKIE_NAME);
33
46
  response.cookies.delete(REFRESH_TOKEN_COOKIE_NAME);
47
+ response.cookies.delete(AUTH_CONFIG_COOKIE_NAME);
34
48
  return response;
35
49
  }
36
50
  if (!accessToken || !isAccessTokenValid) {
@@ -45,8 +59,11 @@ export async function getSession(request) {
45
59
  ...(ipAddress && {
46
60
  'X-Forwarded-For': ipAddress,
47
61
  }),
62
+ ...(fingerprint && {
63
+ [FINGERPRINT_HEADER_KEY]: fingerprint,
64
+ }),
48
65
  },
49
- });
66
+ }, authVersion, authApiBaseUrl);
50
67
  const response = NextResponse.json({
51
68
  ok: true,
52
69
  data: {
@@ -60,6 +77,13 @@ export async function getSession(request) {
60
77
  httpOnly: true,
61
78
  sameSite: 'strict',
62
79
  });
80
+ if (authVersion === 4) {
81
+ response.cookies.set(REFRESH_TOKEN_COOKIE_NAME, data.refreshToken, {
82
+ expires: subMinutes(addDays(new Date(), 15), 2),
83
+ httpOnly: true,
84
+ sameSite: 'strict',
85
+ });
86
+ }
63
87
  return response;
64
88
  }
65
89
  catch {
@@ -72,6 +96,7 @@ export async function getSession(request) {
72
96
  },
73
97
  });
74
98
  response.cookies.delete(REFRESH_TOKEN_COOKIE_NAME);
99
+ response.cookies.delete(AUTH_CONFIG_COOKIE_NAME);
75
100
  return response;
76
101
  }
77
102
  }