@fluxbase/sdk-react 0.1.0-rc.1 → 2026.1.1-rc.10

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.
@@ -0,0 +1,221 @@
1
+ /**
2
+ * SAML SSO hooks for Fluxbase React SDK
3
+ */
4
+
5
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
6
+ import { useFluxbaseClient } from "./context";
7
+ import type { SAMLLoginOptions, SAMLProvider } from "@fluxbase/sdk";
8
+
9
+ /**
10
+ * Hook to get available SAML SSO providers
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * function SAMLProviderList() {
15
+ * const { data: providers, isLoading } = useSAMLProviders()
16
+ *
17
+ * if (isLoading) return <div>Loading...</div>
18
+ *
19
+ * return (
20
+ * <div>
21
+ * {providers?.map(provider => (
22
+ * <button key={provider.id} onClick={() => signInWithSAML(provider.name)}>
23
+ * Sign in with {provider.name}
24
+ * </button>
25
+ * ))}
26
+ * </div>
27
+ * )
28
+ * }
29
+ * ```
30
+ */
31
+ export function useSAMLProviders() {
32
+ const client = useFluxbaseClient();
33
+
34
+ return useQuery<SAMLProvider[]>({
35
+ queryKey: ["fluxbase", "auth", "saml", "providers"],
36
+ queryFn: async () => {
37
+ const { data, error } = await client.auth.getSAMLProviders();
38
+ if (error) throw error;
39
+ return data.providers;
40
+ },
41
+ staleTime: 1000 * 60 * 5, // 5 minutes - providers don't change often
42
+ });
43
+ }
44
+
45
+ /**
46
+ * Hook to get SAML login URL for a provider
47
+ *
48
+ * This hook returns a function to get the login URL for a specific provider.
49
+ * Use this when you need more control over the redirect behavior.
50
+ *
51
+ * @example
52
+ * ```tsx
53
+ * function SAMLLoginButton({ provider }: { provider: string }) {
54
+ * const getSAMLLoginUrl = useGetSAMLLoginUrl()
55
+ *
56
+ * const handleClick = async () => {
57
+ * const { data, error } = await getSAMLLoginUrl.mutateAsync({
58
+ * provider,
59
+ * options: { redirectUrl: window.location.href }
60
+ * })
61
+ * if (!error) {
62
+ * window.location.href = data.url
63
+ * }
64
+ * }
65
+ *
66
+ * return <button onClick={handleClick}>Login with {provider}</button>
67
+ * }
68
+ * ```
69
+ */
70
+ export function useGetSAMLLoginUrl() {
71
+ const client = useFluxbaseClient();
72
+
73
+ return useMutation({
74
+ mutationFn: async ({
75
+ provider,
76
+ options,
77
+ }: {
78
+ provider: string;
79
+ options?: SAMLLoginOptions;
80
+ }) => {
81
+ return await client.auth.getSAMLLoginUrl(provider, options);
82
+ },
83
+ });
84
+ }
85
+
86
+ /**
87
+ * Hook to initiate SAML login (redirects to IdP)
88
+ *
89
+ * This hook returns a mutation that when called, redirects the user to the
90
+ * SAML Identity Provider for authentication.
91
+ *
92
+ * @example
93
+ * ```tsx
94
+ * function SAMLLoginButton() {
95
+ * const signInWithSAML = useSignInWithSAML()
96
+ *
97
+ * return (
98
+ * <button
99
+ * onClick={() => signInWithSAML.mutate({ provider: 'okta' })}
100
+ * disabled={signInWithSAML.isPending}
101
+ * >
102
+ * {signInWithSAML.isPending ? 'Redirecting...' : 'Sign in with Okta'}
103
+ * </button>
104
+ * )
105
+ * }
106
+ * ```
107
+ */
108
+ export function useSignInWithSAML() {
109
+ const client = useFluxbaseClient();
110
+
111
+ return useMutation({
112
+ mutationFn: async ({
113
+ provider,
114
+ options,
115
+ }: {
116
+ provider: string;
117
+ options?: SAMLLoginOptions;
118
+ }) => {
119
+ return await client.auth.signInWithSAML(provider, options);
120
+ },
121
+ });
122
+ }
123
+
124
+ /**
125
+ * Hook to handle SAML callback after IdP authentication
126
+ *
127
+ * Use this in your SAML callback page to complete the authentication flow.
128
+ *
129
+ * @example
130
+ * ```tsx
131
+ * function SAMLCallbackPage() {
132
+ * const handleCallback = useHandleSAMLCallback()
133
+ * const navigate = useNavigate()
134
+ *
135
+ * useEffect(() => {
136
+ * const params = new URLSearchParams(window.location.search)
137
+ * const samlResponse = params.get('SAMLResponse')
138
+ *
139
+ * if (samlResponse) {
140
+ * handleCallback.mutate(
141
+ * { samlResponse },
142
+ * {
143
+ * onSuccess: () => navigate('/dashboard'),
144
+ * onError: (error) => console.error('SAML login failed:', error)
145
+ * }
146
+ * )
147
+ * }
148
+ * }, [])
149
+ *
150
+ * if (handleCallback.isPending) {
151
+ * return <div>Completing sign in...</div>
152
+ * }
153
+ *
154
+ * if (handleCallback.isError) {
155
+ * return <div>Authentication failed: {handleCallback.error.message}</div>
156
+ * }
157
+ *
158
+ * return null
159
+ * }
160
+ * ```
161
+ */
162
+ export function useHandleSAMLCallback() {
163
+ const client = useFluxbaseClient();
164
+ const queryClient = useQueryClient();
165
+
166
+ return useMutation({
167
+ mutationFn: async ({
168
+ samlResponse,
169
+ provider,
170
+ }: {
171
+ samlResponse: string;
172
+ provider?: string;
173
+ }) => {
174
+ return await client.auth.handleSAMLCallback(samlResponse, provider);
175
+ },
176
+ onSuccess: (result) => {
177
+ if (result.data) {
178
+ // Update auth state in React Query cache
179
+ queryClient.setQueryData(
180
+ ["fluxbase", "auth", "session"],
181
+ result.data.session,
182
+ );
183
+ queryClient.setQueryData(
184
+ ["fluxbase", "auth", "user"],
185
+ result.data.user,
186
+ );
187
+ // Invalidate any dependent queries
188
+ queryClient.invalidateQueries({ queryKey: ["fluxbase"] });
189
+ }
190
+ },
191
+ });
192
+ }
193
+
194
+ /**
195
+ * Hook to get SAML Service Provider metadata URL
196
+ *
197
+ * Returns a function that generates the SP metadata URL for a given provider.
198
+ * Use this URL when configuring your SAML IdP.
199
+ *
200
+ * @example
201
+ * ```tsx
202
+ * function SAMLSetupInfo({ provider }: { provider: string }) {
203
+ * const getSAMLMetadataUrl = useSAMLMetadataUrl()
204
+ * const metadataUrl = getSAMLMetadataUrl(provider)
205
+ *
206
+ * return (
207
+ * <div>
208
+ * <p>SP Metadata URL:</p>
209
+ * <code>{metadataUrl}</code>
210
+ * </div>
211
+ * )
212
+ * }
213
+ * ```
214
+ */
215
+ export function useSAMLMetadataUrl() {
216
+ const client = useFluxbaseClient();
217
+
218
+ return (provider: string): string => {
219
+ return client.auth.getSAMLMetadataUrl(provider);
220
+ };
221
+ }