@opexa/portal-components 0.0.1123 → 0.0.1125
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.
- package/dist/client/hooks/useSignInMutation.d.ts +1 -0
- package/dist/client/hooks/useSignInMutation.js +8 -2
- package/dist/components/SignIn/CrazyWin/MobileNumberSignIn.js +1 -1
- package/dist/components/SignIn/CrazyWin/NameAndPasswordSignIn.js +1 -0
- package/dist/components/SignIn/HappyBingo/MobileNumberSignIn.js +1 -1
- package/dist/components/SignIn/HappyBingo/NameAndPasswordSignIn.js +1 -0
- package/dist/components/SignIn/MobileNumberSignIn.js +1 -1
- package/dist/components/SignIn/MobileNumberSignInternational.js +1 -1
- package/dist/components/SignIn/NameAndPasswordSignIn.js +1 -0
- package/dist/components/SignIn/SignIn.lazy.d.ts +5 -0
- package/dist/components/UpdateMobilePhoneNumber/UpdateMobilePhoneNumber.js +3 -3
- package/dist/constants/HeaderKey.d.ts +1 -0
- package/dist/constants/HeaderKey.js +1 -0
- package/dist/handlers/postSession.js +5 -1
- package/dist/services/auth.js +36 -2
- package/dist/ui/Carousel/Carousel.d.ts +45 -45
- package/dist/ui/Carousel/carousel.recipe.d.ts +5 -5
- package/dist/ui/DatePicker/DatePicker.d.ts +72 -72
- package/dist/ui/DatePicker/datePicker.recipe.d.ts +3 -3
- package/dist/ui/Menu/Menu.d.ts +90 -90
- package/dist/ui/Menu/menu.recipe.d.ts +5 -5
- package/dist/ui/Progress/Progress.d.ts +27 -27
- package/dist/ui/Progress/progress.recipe.d.ts +3 -3
- package/package.json +1 -1
|
@@ -4,5 +4,6 @@ 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
|
+
fingerprint?: () => Promise<string | null> | string | null;
|
|
7
8
|
}
|
|
8
9
|
export declare const useSignInMutation: (options?: UseSignInMutationOptions) => UseMutationResult<Authenticator | null, Error, SignInInput>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Capacitor } from '@capacitor/core';
|
|
2
2
|
import { useMutation } from '@tanstack/react-query';
|
|
3
3
|
import { useReCaptcha } from 'next-recaptcha-v3';
|
|
4
|
-
import { RECAPTCHA_HEADER_KEY } from '../../constants/index.js';
|
|
4
|
+
import { FINGERPRINT_HEADER_KEY, RECAPTCHA_HEADER_KEY, } from '../../constants/index.js';
|
|
5
5
|
import { getQueryClient } from '../../utils/getQueryClient.js';
|
|
6
6
|
import { getSignInMutationKey } from '../../utils/mutationKeys.js';
|
|
7
7
|
import { getSessionQueryKey } from '../../utils/queryKeys.js';
|
|
@@ -10,7 +10,7 @@ import { signIn } from '../services/signIn.js';
|
|
|
10
10
|
export const useSignInMutation = (options) => {
|
|
11
11
|
const queryClient = getQueryClient();
|
|
12
12
|
const recaptcha = useReCaptcha();
|
|
13
|
-
const { versionSession, ...config } = options ?? {};
|
|
13
|
+
const { fingerprint, versionSession, ...config } = options ?? {};
|
|
14
14
|
return useMutation({
|
|
15
15
|
...config,
|
|
16
16
|
mutationKey: getSignInMutationKey(),
|
|
@@ -19,6 +19,9 @@ export const useSignInMutation = (options) => {
|
|
|
19
19
|
const token = recaptcha.reCaptchaKey
|
|
20
20
|
? await recaptcha.executeRecaptcha('submit')
|
|
21
21
|
: null;
|
|
22
|
+
const fingerprintValue = versionSession === 'Inplay' && input.type === 'NAME_AND_PASSWORD'
|
|
23
|
+
? await Promise.resolve(fingerprint?.()).catch(() => null)
|
|
24
|
+
: null;
|
|
22
25
|
const authenticator = await signIn(input, {
|
|
23
26
|
headers: {
|
|
24
27
|
...(token && {
|
|
@@ -27,6 +30,9 @@ export const useSignInMutation = (options) => {
|
|
|
27
30
|
...(session.domain && {
|
|
28
31
|
Domain: session.domain,
|
|
29
32
|
}),
|
|
33
|
+
...(fingerprintValue && {
|
|
34
|
+
[FINGERPRINT_HEADER_KEY]: fingerprintValue,
|
|
35
|
+
}),
|
|
30
36
|
...(Capacitor.getPlatform() === 'android'
|
|
31
37
|
? { Channel: 'ANDROID' }
|
|
32
38
|
: { Channel: 'IOS' }),
|
|
@@ -45,7 +45,7 @@ export function MobileNumberSignIn() {
|
|
|
45
45
|
disclaimer: ctx.disclaimer,
|
|
46
46
|
})));
|
|
47
47
|
const signInMutation = useSignInMutation({
|
|
48
|
-
versionSession:
|
|
48
|
+
// versionSession intentionally omitted: only applies to NAME_AND_PASSWORD
|
|
49
49
|
onSuccess: async () => {
|
|
50
50
|
step1Form.reset();
|
|
51
51
|
step2Form.reset();
|
|
@@ -45,6 +45,7 @@ export function NameAndPasswordSignIn() {
|
|
|
45
45
|
disclaimer: ctx.disclaimer,
|
|
46
46
|
})));
|
|
47
47
|
const signInMutation = useSignInMutation({
|
|
48
|
+
fingerprint: signInProps.fingerprint,
|
|
48
49
|
versionSession: signInProps.versionSession,
|
|
49
50
|
onSuccess: async (authenticator) => {
|
|
50
51
|
if (authenticator) {
|
|
@@ -46,7 +46,7 @@ export function MobileNumberSignIn() {
|
|
|
46
46
|
disclaimer: ctx.disclaimer,
|
|
47
47
|
})));
|
|
48
48
|
const signInMutation = useSignInMutation({
|
|
49
|
-
versionSession:
|
|
49
|
+
// versionSession intentionally omitted: only applies to NAME_AND_PASSWORD
|
|
50
50
|
onSuccess: async () => {
|
|
51
51
|
step1Form.reset();
|
|
52
52
|
step2Form.reset();
|
|
@@ -42,6 +42,7 @@ export function NameAndPasswordSignIn() {
|
|
|
42
42
|
disclaimer: ctx.disclaimer,
|
|
43
43
|
})));
|
|
44
44
|
const signInMutation = useSignInMutation({
|
|
45
|
+
fingerprint: signInProps.fingerprint,
|
|
45
46
|
versionSession: signInProps.versionSession,
|
|
46
47
|
onSuccess: async (authenticator) => {
|
|
47
48
|
if (authenticator) {
|
|
@@ -53,7 +53,7 @@ export function MobileNumberSignIn() {
|
|
|
53
53
|
termsOfUse: ctx.termsOfUse,
|
|
54
54
|
})));
|
|
55
55
|
const signInMutation = useSignInMutation({
|
|
56
|
-
versionSession:
|
|
56
|
+
// versionSession intentionally omitted: only applies to NAME_AND_PASSWORD
|
|
57
57
|
onSuccess: async () => {
|
|
58
58
|
step1Form.reset();
|
|
59
59
|
step2Form.reset();
|
|
@@ -80,7 +80,7 @@ export function MobileNumberSignInInternational() {
|
|
|
80
80
|
disclaimer: ctx.disclaimer,
|
|
81
81
|
})));
|
|
82
82
|
const signInMutation = useSignInMutation({
|
|
83
|
-
versionSession:
|
|
83
|
+
// versionSession intentionally omitted: only applies to NAME_AND_PASSWORD
|
|
84
84
|
onSuccess: async () => {
|
|
85
85
|
step1Form.reset();
|
|
86
86
|
step2Form.reset();
|
|
@@ -55,6 +55,7 @@ export function NameAndPasswordSignIn() {
|
|
|
55
55
|
})));
|
|
56
56
|
const [formType, setFormType] = useState('NAME_AND_PASSWORD');
|
|
57
57
|
const signInMutation = useSignInMutation({
|
|
58
|
+
fingerprint: signInProps.fingerprint,
|
|
58
59
|
versionSession: signInProps.versionSession,
|
|
59
60
|
onSuccess: async (authenticator) => {
|
|
60
61
|
if (authenticator) {
|
|
@@ -31,5 +31,10 @@ export interface SignInProps extends UseSignInProps {
|
|
|
31
31
|
* - `Inplay`: `${AUTH_ENDPOINT}/v3/inplay/sessions`
|
|
32
32
|
*/
|
|
33
33
|
versionSession?: VersionSession;
|
|
34
|
+
/**
|
|
35
|
+
* Optional browser fingerprint provider. For Inplay NAME_AND_PASSWORD
|
|
36
|
+
* sign-ins, pass `() => sdk.fingerprint()` from the consuming app.
|
|
37
|
+
*/
|
|
38
|
+
fingerprint?: () => Promise<string | null> | string | null;
|
|
34
39
|
}
|
|
35
40
|
export declare function SignIn(props: SignInProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -30,11 +30,11 @@ export function UpdateMobilePhoneNumber() {
|
|
|
30
30
|
const accountQuery = useAccountQuery();
|
|
31
31
|
const account = accountQuery.data;
|
|
32
32
|
const isAccountLoading = accountQuery.isLoading;
|
|
33
|
-
const
|
|
33
|
+
const isMobileNumberVerified = account?.mobileNumberVerified === true;
|
|
34
34
|
const hasExecuted = useRef(false);
|
|
35
35
|
useEffect(() => {
|
|
36
36
|
if (!isAccountLoading && !!account && !hasExecuted.current) {
|
|
37
|
-
if (!
|
|
37
|
+
if (!isMobileNumberVerified) {
|
|
38
38
|
globalStore.updateMobilePhoneNumber.setOpen(true);
|
|
39
39
|
}
|
|
40
40
|
else {
|
|
@@ -45,7 +45,7 @@ export function UpdateMobilePhoneNumber() {
|
|
|
45
45
|
}, [
|
|
46
46
|
isAccountLoading,
|
|
47
47
|
account,
|
|
48
|
-
|
|
48
|
+
isMobileNumberVerified,
|
|
49
49
|
globalStore.updateMobilePhoneNumber,
|
|
50
50
|
]);
|
|
51
51
|
const [step, setStep] = useState(1);
|
|
@@ -2,3 +2,4 @@ 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 FINGERPRINT_HEADER_KEY = 'Fingerprint';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { addDays, addMinutes, subMinutes } from 'date-fns';
|
|
2
2
|
import { NextResponse } from 'next/server';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { ACCESS_TOKEN_COOKIE_NAME, DOMAIN_HEADER_KEY, RECAPTCHA_HEADER_KEY, REFRESH_TOKEN_COOKIE_NAME, SESSION_VERSION_HEADER_KEY, } from '../constants/index.js';
|
|
4
|
+
import { ACCESS_TOKEN_COOKIE_NAME, DOMAIN_HEADER_KEY, FINGERPRINT_HEADER_KEY, RECAPTCHA_HEADER_KEY, REFRESH_TOKEN_COOKIE_NAME, SESSION_VERSION_HEADER_KEY, } from '../constants/index.js';
|
|
5
5
|
import { createSession } from '../services/auth.js';
|
|
6
6
|
const CreateSessionDefinition = z.union([
|
|
7
7
|
z.object({
|
|
@@ -41,6 +41,7 @@ export async function postSession(request) {
|
|
|
41
41
|
}
|
|
42
42
|
const recaptcha = request.headers.get(RECAPTCHA_HEADER_KEY);
|
|
43
43
|
const domain = request.headers.get(DOMAIN_HEADER_KEY);
|
|
44
|
+
const fingerprint = request.headers.get(FINGERPRINT_HEADER_KEY);
|
|
44
45
|
const versionSessionHeader = request.headers.get(SESSION_VERSION_HEADER_KEY);
|
|
45
46
|
const versionSession = versionSessionHeader === 'Inplay' ? 'Inplay' : 'default';
|
|
46
47
|
try {
|
|
@@ -52,6 +53,9 @@ export async function postSession(request) {
|
|
|
52
53
|
...(domain && {
|
|
53
54
|
[DOMAIN_HEADER_KEY]: domain,
|
|
54
55
|
}),
|
|
56
|
+
...(fingerprint && {
|
|
57
|
+
[FINGERPRINT_HEADER_KEY]: fingerprint,
|
|
58
|
+
}),
|
|
55
59
|
...(userAgent && {
|
|
56
60
|
'User-Agent': userAgent,
|
|
57
61
|
}),
|
package/dist/services/auth.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AUTH_ENDPOINT } from '../constants/index.js';
|
|
1
|
+
import { AUTH_ENDPOINT, FINGERPRINT_HEADER_KEY } from '../constants/index.js';
|
|
2
2
|
import { httpRequest } from './httpRequest.js';
|
|
3
3
|
import { sha256 } from './sha256.js';
|
|
4
4
|
const SESSION_ENDPOINTS = {
|
|
@@ -29,8 +29,42 @@ export async function createSession(input, options, versionSession = 'default')
|
|
|
29
29
|
new Headers(options?.headers).forEach((value, key) => {
|
|
30
30
|
headers.set(key, value);
|
|
31
31
|
});
|
|
32
|
+
// `versionSession` only applies to NAME_AND_PASSWORD sign-ins. All other
|
|
33
|
+
// auth types (MOBILE_NUMBER, MAYA, SOCIALS, CABINET, SINGLE_USE_TOKEN) are
|
|
34
|
+
// forced to the default `/sessions` endpoint.
|
|
35
|
+
const effectiveVersionSession = input.type === 'NAME_AND_PASSWORD' ? versionSession : 'default';
|
|
36
|
+
// The `Fingerprint` header is only meaningful for the Inplay
|
|
37
|
+
// NAME_AND_PASSWORD endpoint (`/v3/inplay/sessions`). Strip it for any
|
|
38
|
+
// other combination to avoid leaking it to upstream endpoints that don't
|
|
39
|
+
// expect it.
|
|
40
|
+
if (effectiveVersionSession !== 'Inplay' ||
|
|
41
|
+
input.type !== 'NAME_AND_PASSWORD') {
|
|
42
|
+
headers.delete(FINGERPRINT_HEADER_KEY);
|
|
43
|
+
}
|
|
32
44
|
try {
|
|
33
|
-
|
|
45
|
+
// The Inplay `/v3/inplay/sessions` endpoint wraps its payload in
|
|
46
|
+
// `{ data: { ... } }` (same shape as `/v2/sessions`), while the
|
|
47
|
+
// default `/sessions` endpoint returns the flat shape directly.
|
|
48
|
+
// Unwrap the Inplay response so callers can treat both consistently
|
|
49
|
+
// via the existing `CreateSessionMutation` union.
|
|
50
|
+
if (effectiveVersionSession === 'Inplay') {
|
|
51
|
+
const wrapped = await httpRequest.json(`${AUTH_ENDPOINT}${SESSION_ENDPOINTS[effectiveVersionSession]}`, {
|
|
52
|
+
...options,
|
|
53
|
+
method: 'POST',
|
|
54
|
+
headers,
|
|
55
|
+
});
|
|
56
|
+
if (wrapped.data.authenticator) {
|
|
57
|
+
return {
|
|
58
|
+
authenticator: wrapped.data.authenticator,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
session: wrapped.data.session,
|
|
63
|
+
accessToken: wrapped.data.accessToken,
|
|
64
|
+
refreshToken: wrapped.data.refreshToken,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return await httpRequest.json(`${AUTH_ENDPOINT}${SESSION_ENDPOINTS[effectiveVersionSession]}`, {
|
|
34
68
|
...options,
|
|
35
69
|
method: 'POST',
|
|
36
70
|
headers,
|