@instroc/auth 1.1.1 → 1.2.0

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.
@@ -29,7 +29,7 @@ function authErrorFromResponse(response, data, fallbackMessage) {
29
29
 
30
30
  // src/version.ts
31
31
  var SDK_NAME = "instroc-auth";
32
- var SDK_VERSION = true ? "1.1.1" : "0.0.0-dev";
32
+ var SDK_VERSION = true ? "1.2.0" : "0.0.0-dev";
33
33
  function withSdkHeader(init) {
34
34
  const headers = new Headers(init?.headers ?? {});
35
35
  headers.set("X-Instroc-SDK", `${SDK_NAME}/${SDK_VERSION}`);
@@ -42,7 +42,7 @@ var AuthContext = createContext(null);
42
42
  var STORAGE_KEY = "instroc_auth_session";
43
43
  var WARNING_SESSION_KEY = "instroc_auth_sdk_warning_seen";
44
44
  function noteDeprecationWarning(response) {
45
- const warning = response.headers.get("X-Instroc-SDK-Warning");
45
+ const warning = response.headers?.get?.("X-Instroc-SDK-Warning");
46
46
  if (!warning)
47
47
  return;
48
48
  if (typeof window === "undefined")
@@ -596,6 +596,30 @@ function useAuthRequired() {
596
596
  }
597
597
  return { user, session, loading: false };
598
598
  }
599
+ function useIsOwner() {
600
+ const { user, session, loading } = useAuthContext();
601
+ if (loading || !user || !session)
602
+ return false;
603
+ if (user.is_owner === true)
604
+ return true;
605
+ const claim = decodeIsOwnerClaim(session.access_token);
606
+ return claim === true;
607
+ }
608
+ function decodeIsOwnerClaim(accessToken) {
609
+ try {
610
+ const parts = accessToken.split(".");
611
+ if (parts.length !== 3)
612
+ return void 0;
613
+ const payload = parts[1];
614
+ const base64 = payload.replace(/-/g, "+").replace(/_/g, "/");
615
+ const padded = base64 + "=".repeat((4 - base64.length % 4) % 4);
616
+ const json = typeof atob !== "undefined" ? atob(padded) : Buffer.from(padded, "base64").toString("utf-8");
617
+ const decoded = JSON.parse(json);
618
+ return decoded.is_owner;
619
+ } catch {
620
+ return void 0;
621
+ }
622
+ }
599
623
 
600
624
  // src/forms/use-form-action.ts
601
625
  function resolveErrorMessage(err, messages, fallback) {
@@ -962,6 +986,7 @@ export {
962
986
  useUser,
963
987
  useSession,
964
988
  useAuthRequired,
989
+ useIsOwner,
965
990
  useLoginForm,
966
991
  useSignupForm,
967
992
  useOtpForm,
package/dist/forms.d.ts CHANGED
@@ -1 +1 @@
1
- export { M as MessageOverrides, O as OnErrorResult, m as UseForgotPasswordFormOptions, n as UseForgotPasswordFormReturn, U as UseLoginFormOptions, h as UseLoginFormReturn, k as UseOtpFormOptions, l as UseOtpFormReturn, o as UseResetPasswordFormOptions, p as UseResetPasswordFormReturn, i as UseSignupFormOptions, j as UseSignupFormReturn, f as useForgotPasswordForm, u as useLoginForm, e as useOtpForm, g as useResetPasswordForm, d as useSignupForm } from './index-D4rCSC9H.js';
1
+ export { M as MessageOverrides, O as OnErrorResult, m as UseForgotPasswordFormOptions, n as UseForgotPasswordFormReturn, U as UseLoginFormOptions, h as UseLoginFormReturn, k as UseOtpFormOptions, l as UseOtpFormReturn, o as UseResetPasswordFormOptions, p as UseResetPasswordFormReturn, i as UseSignupFormOptions, j as UseSignupFormReturn, f as useForgotPasswordForm, u as useLoginForm, e as useOtpForm, g as useResetPasswordForm, d as useSignupForm } from './index-iglVgSQI.js';
package/dist/forms.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  useOtpForm,
5
5
  useResetPasswordForm,
6
6
  useSignupForm
7
- } from "./chunk-T7NGX4DQ.js";
7
+ } from "./chunk-E6J2FYDA.js";
8
8
  export {
9
9
  useForgotPasswordForm,
10
10
  useLoginForm,
@@ -6,6 +6,13 @@ interface AuthUser {
6
6
  avatar_url: string | null;
7
7
  metadata: Record<string, unknown>;
8
8
  created_at: string;
9
+ /**
10
+ * True for the project owner (first user or explicitly designated). Mirrors
11
+ * the `is_owner` JWT claim used for RLS bypass on the server. Templates
12
+ * gate admin UIs (/admin, /studio) on this field so only the owner sees
13
+ * CRUD controls in production.
14
+ */
15
+ is_owner?: boolean;
9
16
  }
10
17
  interface AuthSession {
11
18
  access_token: string;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AuthProviderProps, a as AuthContextValue, b as AuthUser, c as AuthSession } from './index-D4rCSC9H.js';
2
- export { r as AuthConfig, w as AuthResponse, q as AuthState, L as LoginCredentials, M as MessageOverrides, s as OAuthProvider, O as OnErrorResult, R as RefreshResponse, S as SignupCredentials, t as SignupResult, v as UpdateProfileData, m as UseForgotPasswordFormOptions, n as UseForgotPasswordFormReturn, U as UseLoginFormOptions, h as UseLoginFormReturn, k as UseOtpFormOptions, l as UseOtpFormReturn, o as UseResetPasswordFormOptions, p as UseResetPasswordFormReturn, i as UseSignupFormOptions, j as UseSignupFormReturn, V as VisibilityConfig, f as useForgotPasswordForm, u as useLoginForm, e as useOtpForm, g as useResetPasswordForm, d as useSignupForm } from './index-D4rCSC9H.js';
1
+ import { A as AuthProviderProps, a as AuthContextValue, b as AuthUser, c as AuthSession } from './index-iglVgSQI.js';
2
+ export { r as AuthConfig, w as AuthResponse, q as AuthState, L as LoginCredentials, M as MessageOverrides, s as OAuthProvider, O as OnErrorResult, R as RefreshResponse, S as SignupCredentials, t as SignupResult, v as UpdateProfileData, m as UseForgotPasswordFormOptions, n as UseForgotPasswordFormReturn, U as UseLoginFormOptions, h as UseLoginFormReturn, k as UseOtpFormOptions, l as UseOtpFormReturn, o as UseResetPasswordFormOptions, p as UseResetPasswordFormReturn, i as UseSignupFormOptions, j as UseSignupFormReturn, V as VisibilityConfig, f as useForgotPasswordForm, u as useLoginForm, e as useOtpForm, g as useResetPasswordForm, d as useSignupForm } from './index-iglVgSQI.js';
3
3
 
4
4
  declare function AuthProvider({ children, projectId: initialProjectId, baseUrl, persistSession, onAuthStateChange, }: AuthProviderProps): JSX.Element;
5
5
  declare function useAuthContext(): AuthContextValue;
@@ -22,6 +22,18 @@ declare function useAuthRequired(): {
22
22
  session: AuthSession | null;
23
23
  loading: boolean;
24
24
  };
25
+ /**
26
+ * Returns true if the current user is the project owner. Used by templates
27
+ * to gate admin/studio routes.
28
+ *
29
+ * Reads `user.is_owner` first (populated by the `/me` endpoint). Falls back
30
+ * to decoding the access token's `is_owner` claim so the check is accurate
31
+ * immediately after login (the login response doesn't echo is_owner — only
32
+ * `/me` does, and that only runs on mount).
33
+ *
34
+ * Returns `false` while loading or when unauthenticated.
35
+ */
36
+ declare function useIsOwner(): boolean;
25
37
 
26
38
  /**
27
39
  * Typed error thrown by every `@instroc/auth` method when the server responds
@@ -54,4 +66,4 @@ declare class AuthError extends Error {
54
66
  constructor(message: string, status: number, code?: string);
55
67
  }
56
68
 
57
- export { AuthContextValue, AuthError, AuthProvider, AuthProviderProps, AuthSession, AuthUser, useAuth, useAuthContext, useAuthRequired, useSession, useUser };
69
+ export { AuthContextValue, AuthError, AuthProvider, AuthProviderProps, AuthSession, AuthUser, useAuth, useAuthContext, useAuthRequired, useIsOwner, useSession, useUser };
package/dist/index.js CHANGED
@@ -5,13 +5,14 @@ import {
5
5
  useAuthContext,
6
6
  useAuthRequired,
7
7
  useForgotPasswordForm,
8
+ useIsOwner,
8
9
  useLoginForm,
9
10
  useOtpForm,
10
11
  useResetPasswordForm,
11
12
  useSession,
12
13
  useSignupForm,
13
14
  useUser
14
- } from "./chunk-T7NGX4DQ.js";
15
+ } from "./chunk-E6J2FYDA.js";
15
16
  export {
16
17
  AuthError,
17
18
  AuthProvider,
@@ -19,6 +20,7 @@ export {
19
20
  useAuthContext,
20
21
  useAuthRequired,
21
22
  useForgotPasswordForm,
23
+ useIsOwner,
22
24
  useLoginForm,
23
25
  useOtpForm,
24
26
  useResetPasswordForm,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instroc/auth",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
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,10 +18,6 @@
18
18
  "files": [
19
19
  "dist"
20
20
  ],
21
- "scripts": {
22
- "build": "tsup",
23
- "dev": "tsup --watch"
24
- },
25
21
  "peerDependencies": {
26
22
  "react": "^18.0.0"
27
23
  },
@@ -39,5 +35,9 @@
39
35
  },
40
36
  "publishConfig": {
41
37
  "access": "public"
38
+ },
39
+ "scripts": {
40
+ "build": "tsup",
41
+ "dev": "tsup --watch"
42
42
  }
43
- }
43
+ }