@instroc/auth 1.2.0 → 1.3.1
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/{chunk-E6J2FYDA.js → chunk-4FR5RRCB.js} +66 -25
- package/dist/forms.js +1 -1
- package/dist/index.d.ts +31 -1
- package/dist/index.js +3 -1
- package/package.json +6 -6
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
// src/forms/use-login-form.ts
|
|
2
|
-
import { useState as
|
|
2
|
+
import { useState as useState3, useCallback as useCallback2, useRef as useRef2, useEffect as useEffect3 } from "react";
|
|
3
|
+
|
|
4
|
+
// src/use-auth.ts
|
|
5
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
3
6
|
|
|
4
7
|
// src/provider.tsx
|
|
5
8
|
import {
|
|
@@ -29,7 +32,7 @@ function authErrorFromResponse(response, data, fallbackMessage) {
|
|
|
29
32
|
|
|
30
33
|
// src/version.ts
|
|
31
34
|
var SDK_NAME = "instroc-auth";
|
|
32
|
-
var SDK_VERSION = true ? "1.
|
|
35
|
+
var SDK_VERSION = true ? "1.3.1" : "0.0.0-dev";
|
|
33
36
|
function withSdkHeader(init) {
|
|
34
37
|
const headers = new Headers(init?.headers ?? {});
|
|
35
38
|
headers.set("X-Instroc-SDK", `${SDK_NAME}/${SDK_VERSION}`);
|
|
@@ -605,6 +608,43 @@ function useIsOwner() {
|
|
|
605
608
|
const claim = decodeIsOwnerClaim(session.access_token);
|
|
606
609
|
return claim === true;
|
|
607
610
|
}
|
|
611
|
+
function useIsWorkspaceMember() {
|
|
612
|
+
const [isMember, setIsMember] = useState2(() => isDevHost());
|
|
613
|
+
useEffect2(() => {
|
|
614
|
+
if (typeof window === "undefined")
|
|
615
|
+
return;
|
|
616
|
+
let cancelled = false;
|
|
617
|
+
(async () => {
|
|
618
|
+
try {
|
|
619
|
+
const res = await fetch("/__instroc/workspace-status", {
|
|
620
|
+
credentials: "include",
|
|
621
|
+
cache: "no-store"
|
|
622
|
+
});
|
|
623
|
+
if (cancelled)
|
|
624
|
+
return;
|
|
625
|
+
if (!res.ok) {
|
|
626
|
+
setIsMember(isDevHost());
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
const data = await res.json();
|
|
630
|
+
setIsMember(data.isWorkspaceMember === true);
|
|
631
|
+
} catch {
|
|
632
|
+
if (!cancelled)
|
|
633
|
+
setIsMember(isDevHost());
|
|
634
|
+
}
|
|
635
|
+
})();
|
|
636
|
+
return () => {
|
|
637
|
+
cancelled = true;
|
|
638
|
+
};
|
|
639
|
+
}, []);
|
|
640
|
+
return isMember;
|
|
641
|
+
}
|
|
642
|
+
function isDevHost() {
|
|
643
|
+
if (typeof window === "undefined")
|
|
644
|
+
return false;
|
|
645
|
+
const h = window.location.hostname;
|
|
646
|
+
return h === "localhost" || h === "127.0.0.1" || h.endsWith(".fly.dev") || h.endsWith(".workers.dev") || h === "preview.instroc.app";
|
|
647
|
+
}
|
|
608
648
|
function decodeIsOwnerClaim(accessToken) {
|
|
609
649
|
try {
|
|
610
650
|
const parts = accessToken.split(".");
|
|
@@ -647,10 +687,10 @@ function applyErrorResult(err, onError, messages, fallback, setError) {
|
|
|
647
687
|
function useLoginForm(options = {}) {
|
|
648
688
|
const { login, user } = useAuth();
|
|
649
689
|
const { onSuccess, onNeedsVerification, onError, messages } = options;
|
|
650
|
-
const [loading, setLoading] =
|
|
651
|
-
const [error, setError] =
|
|
690
|
+
const [loading, setLoading] = useState3(false);
|
|
691
|
+
const [error, setError] = useState3(null);
|
|
652
692
|
const mountedRef = useRef2(true);
|
|
653
|
-
|
|
693
|
+
useEffect3(() => {
|
|
654
694
|
mountedRef.current = true;
|
|
655
695
|
return () => {
|
|
656
696
|
mountedRef.current = false;
|
|
@@ -702,14 +742,14 @@ function useLoginForm(options = {}) {
|
|
|
702
742
|
}
|
|
703
743
|
|
|
704
744
|
// src/forms/use-signup-form.ts
|
|
705
|
-
import { useState as
|
|
745
|
+
import { useState as useState4, useCallback as useCallback3, useRef as useRef3, useEffect as useEffect4 } from "react";
|
|
706
746
|
function useSignupForm(options = {}) {
|
|
707
747
|
const { signup } = useAuth();
|
|
708
748
|
const { onSuccess, onNeedsVerification, onNeedsApproval, onError, messages } = options;
|
|
709
|
-
const [loading, setLoading] =
|
|
710
|
-
const [error, setError] =
|
|
749
|
+
const [loading, setLoading] = useState4(false);
|
|
750
|
+
const [error, setError] = useState4(null);
|
|
711
751
|
const mountedRef = useRef3(true);
|
|
712
|
-
|
|
752
|
+
useEffect4(() => {
|
|
713
753
|
mountedRef.current = true;
|
|
714
754
|
return () => {
|
|
715
755
|
mountedRef.current = false;
|
|
@@ -766,7 +806,7 @@ function useSignupForm(options = {}) {
|
|
|
766
806
|
}
|
|
767
807
|
|
|
768
808
|
// src/forms/use-otp-form.ts
|
|
769
|
-
import { useState as
|
|
809
|
+
import { useState as useState5, useCallback as useCallback4, useRef as useRef4, useEffect as useEffect5 } from "react";
|
|
770
810
|
function useOtpForm(options) {
|
|
771
811
|
const { verifyOTP, resendOTP } = useAuth();
|
|
772
812
|
const {
|
|
@@ -777,18 +817,18 @@ function useOtpForm(options) {
|
|
|
777
817
|
messages,
|
|
778
818
|
resendCooldownSeconds = 60
|
|
779
819
|
} = options;
|
|
780
|
-
const [loading, setLoading] =
|
|
781
|
-
const [resending, setResending] =
|
|
782
|
-
const [resendCooldown, setResendCooldown] =
|
|
783
|
-
const [error, setError] =
|
|
820
|
+
const [loading, setLoading] = useState5(false);
|
|
821
|
+
const [resending, setResending] = useState5(false);
|
|
822
|
+
const [resendCooldown, setResendCooldown] = useState5(0);
|
|
823
|
+
const [error, setError] = useState5(null);
|
|
784
824
|
const mountedRef = useRef4(true);
|
|
785
|
-
|
|
825
|
+
useEffect5(() => {
|
|
786
826
|
mountedRef.current = true;
|
|
787
827
|
return () => {
|
|
788
828
|
mountedRef.current = false;
|
|
789
829
|
};
|
|
790
830
|
}, []);
|
|
791
|
-
|
|
831
|
+
useEffect5(() => {
|
|
792
832
|
if (resendCooldown <= 0)
|
|
793
833
|
return;
|
|
794
834
|
const id = setTimeout(() => setResendCooldown((s) => s - 1), 1e3);
|
|
@@ -870,15 +910,15 @@ function useOtpForm(options) {
|
|
|
870
910
|
}
|
|
871
911
|
|
|
872
912
|
// src/forms/use-forgot-password-form.ts
|
|
873
|
-
import { useState as
|
|
913
|
+
import { useState as useState6, useCallback as useCallback5, useRef as useRef5, useEffect as useEffect6 } from "react";
|
|
874
914
|
function useForgotPasswordForm(options = {}) {
|
|
875
915
|
const { forgotPassword } = useAuth();
|
|
876
916
|
const { onSuccess, onError, messages } = options;
|
|
877
|
-
const [loading, setLoading] =
|
|
878
|
-
const [submitted, setSubmitted] =
|
|
879
|
-
const [error, setError] =
|
|
917
|
+
const [loading, setLoading] = useState6(false);
|
|
918
|
+
const [submitted, setSubmitted] = useState6(false);
|
|
919
|
+
const [error, setError] = useState6(null);
|
|
880
920
|
const mountedRef = useRef5(true);
|
|
881
|
-
|
|
921
|
+
useEffect6(() => {
|
|
882
922
|
mountedRef.current = true;
|
|
883
923
|
return () => {
|
|
884
924
|
mountedRef.current = false;
|
|
@@ -933,14 +973,14 @@ function useForgotPasswordForm(options = {}) {
|
|
|
933
973
|
}
|
|
934
974
|
|
|
935
975
|
// src/forms/use-reset-password-form.ts
|
|
936
|
-
import { useState as
|
|
976
|
+
import { useState as useState7, useCallback as useCallback6, useRef as useRef6, useEffect as useEffect7 } from "react";
|
|
937
977
|
function useResetPasswordForm(options) {
|
|
938
978
|
const { resetPassword } = useAuth();
|
|
939
979
|
const { token, onSuccess, onError, messages } = options;
|
|
940
|
-
const [loading, setLoading] =
|
|
941
|
-
const [error, setError] =
|
|
980
|
+
const [loading, setLoading] = useState7(false);
|
|
981
|
+
const [error, setError] = useState7(null);
|
|
942
982
|
const mountedRef = useRef6(true);
|
|
943
|
-
|
|
983
|
+
useEffect7(() => {
|
|
944
984
|
mountedRef.current = true;
|
|
945
985
|
return () => {
|
|
946
986
|
mountedRef.current = false;
|
|
@@ -987,6 +1027,7 @@ export {
|
|
|
987
1027
|
useSession,
|
|
988
1028
|
useAuthRequired,
|
|
989
1029
|
useIsOwner,
|
|
1030
|
+
useIsWorkspaceMember,
|
|
990
1031
|
useLoginForm,
|
|
991
1032
|
useSignupForm,
|
|
992
1033
|
useOtpForm,
|
package/dist/forms.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -34,6 +34,36 @@ declare function useAuthRequired(): {
|
|
|
34
34
|
* Returns `false` while loading or when unauthenticated.
|
|
35
35
|
*/
|
|
36
36
|
declare function useIsOwner(): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Minimal JWT payload decoder — no signature check (the server already
|
|
39
|
+
* verified it). Returns undefined if the token is malformed. We only read
|
|
40
|
+
* the `is_owner` boolean claim, which the BaaS auth signer sets from
|
|
41
|
+
* `_users.is_owner`.
|
|
42
|
+
*/
|
|
43
|
+
/**
|
|
44
|
+
* Returns true if the current visitor is a member of the Instroc workspace
|
|
45
|
+
* that owns this published app. Used by premium templates to gate owner-only
|
|
46
|
+
* UI such as `/admin` or `/studio` routes.
|
|
47
|
+
*
|
|
48
|
+
* This is distinct from {@link useIsOwner} — workspace members are the humans
|
|
49
|
+
* who built the project (via Instroc), whereas app users (BaaS `_users`) are
|
|
50
|
+
* the end users of the published app. The two populations never overlap, so
|
|
51
|
+
* `useIsOwner` always returns `false` for regular app visitors. Admin UI on
|
|
52
|
+
* premium templates should gate on this hook instead.
|
|
53
|
+
*
|
|
54
|
+
* Implementation: calls `GET /__instroc/workspace-status` on the subdomain
|
|
55
|
+
* router, which validates the `instroc_wa` cookie (HttpOnly, set after
|
|
56
|
+
* Instroc workspace login) against the project's `workspaceId`. The same
|
|
57
|
+
* cookie is what the privacy gate uses to allow workspace members into
|
|
58
|
+
* private apps.
|
|
59
|
+
*
|
|
60
|
+
* Dev/preview note: when running on `localhost`, `*.fly.dev`, `*.workers.dev`,
|
|
61
|
+
* or `preview.instroc.app` (dev-session HMR, editor preview iframe, published
|
|
62
|
+
* preview snapshots), the hook returns `true` so template authors can see
|
|
63
|
+
* admin UI while building. In production (`*.instroc.app` subdomains and
|
|
64
|
+
* custom domains) the server answer is authoritative.
|
|
65
|
+
*/
|
|
66
|
+
declare function useIsWorkspaceMember(): boolean;
|
|
37
67
|
|
|
38
68
|
/**
|
|
39
69
|
* Typed error thrown by every `@instroc/auth` method when the server responds
|
|
@@ -66,4 +96,4 @@ declare class AuthError extends Error {
|
|
|
66
96
|
constructor(message: string, status: number, code?: string);
|
|
67
97
|
}
|
|
68
98
|
|
|
69
|
-
export { AuthContextValue, AuthError, AuthProvider, AuthProviderProps, AuthSession, AuthUser, useAuth, useAuthContext, useAuthRequired, useIsOwner, useSession, useUser };
|
|
99
|
+
export { AuthContextValue, AuthError, AuthProvider, AuthProviderProps, AuthSession, AuthUser, useAuth, useAuthContext, useAuthRequired, useIsOwner, useIsWorkspaceMember, useSession, useUser };
|
package/dist/index.js
CHANGED
|
@@ -6,13 +6,14 @@ import {
|
|
|
6
6
|
useAuthRequired,
|
|
7
7
|
useForgotPasswordForm,
|
|
8
8
|
useIsOwner,
|
|
9
|
+
useIsWorkspaceMember,
|
|
9
10
|
useLoginForm,
|
|
10
11
|
useOtpForm,
|
|
11
12
|
useResetPasswordForm,
|
|
12
13
|
useSession,
|
|
13
14
|
useSignupForm,
|
|
14
15
|
useUser
|
|
15
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-4FR5RRCB.js";
|
|
16
17
|
export {
|
|
17
18
|
AuthError,
|
|
18
19
|
AuthProvider,
|
|
@@ -21,6 +22,7 @@ export {
|
|
|
21
22
|
useAuthRequired,
|
|
22
23
|
useForgotPasswordForm,
|
|
23
24
|
useIsOwner,
|
|
25
|
+
useIsWorkspaceMember,
|
|
24
26
|
useLoginForm,
|
|
25
27
|
useOtpForm,
|
|
26
28
|
useResetPasswordForm,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instroc/auth",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Authentication hooks for Instroc Cloud — useAuth, useUser, AuthProvider, and headless form hooks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
"files": [
|
|
19
19
|
"dist"
|
|
20
20
|
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup",
|
|
23
|
+
"dev": "tsup --watch"
|
|
24
|
+
},
|
|
21
25
|
"peerDependencies": {
|
|
22
26
|
"react": "^18.0.0"
|
|
23
27
|
},
|
|
@@ -35,9 +39,5 @@
|
|
|
35
39
|
},
|
|
36
40
|
"publishConfig": {
|
|
37
41
|
"access": "public"
|
|
38
|
-
},
|
|
39
|
-
"scripts": {
|
|
40
|
-
"build": "tsup",
|
|
41
|
-
"dev": "tsup --watch"
|
|
42
42
|
}
|
|
43
|
-
}
|
|
43
|
+
}
|