@carlonicora/nextjs-jsonapi 1.24.3 → 1.25.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/{BlockNoteEditor-OFSTXGZX.js → BlockNoteEditor-7WAWEZVW.js} +13 -13
- package/dist/{BlockNoteEditor-OFSTXGZX.js.map → BlockNoteEditor-7WAWEZVW.js.map} +1 -1
- package/dist/{BlockNoteEditor-TJNLCNIP.mjs → BlockNoteEditor-UNVKGZ2G.mjs} +3 -3
- package/dist/billing/index.js +342 -342
- package/dist/billing/index.mjs +2 -2
- package/dist/{chunk-H5JZ5E7M.mjs → chunk-6BDOZDZ3.mjs} +1247 -54
- package/dist/chunk-6BDOZDZ3.mjs.map +1 -0
- package/dist/{chunk-EJALOG7L.js → chunk-JI6BDV7L.js} +1598 -405
- package/dist/chunk-JI6BDV7L.js.map +1 -0
- package/dist/{chunk-5U4NJJOF.mjs → chunk-LNBT2YPZ.mjs} +289 -2
- package/dist/chunk-LNBT2YPZ.mjs.map +1 -0
- package/dist/{chunk-NQVPCNRS.js → chunk-O3LLMGP7.js} +290 -3
- package/dist/chunk-O3LLMGP7.js.map +1 -0
- package/dist/client/index.d.mts +96 -1
- package/dist/client/index.d.ts +96 -1
- package/dist/client/index.js +9 -3
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +8 -2
- package/dist/components/index.d.mts +225 -1
- package/dist/components/index.d.ts +225 -1
- package/dist/components/index.js +25 -3
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +24 -2
- package/dist/contexts/index.js +3 -3
- package/dist/contexts/index.mjs +2 -2
- package/dist/core/index.d.mts +108 -1
- package/dist/core/index.d.ts +108 -1
- package/dist/core/index.js +14 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +13 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +14 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +13 -1
- package/dist/oauth.interface-DsZ5ecSX.d.mts +119 -0
- package/dist/oauth.interface-vL7za9Bz.d.ts +119 -0
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +1 -1
- package/package.json +3 -2
- package/src/client/index.ts +1 -0
- package/src/components/index.ts +1 -0
- package/src/core/index.ts +3 -0
- package/src/core/registry/ModuleRegistry.ts +2 -0
- package/src/features/index.ts +1 -0
- package/src/features/oauth/atoms/index.ts +1 -0
- package/src/features/oauth/atoms/oauth.atoms.ts +131 -0
- package/src/features/oauth/components/OAuthClientCard.tsx +105 -0
- package/src/features/oauth/components/OAuthClientDetail.tsx +269 -0
- package/src/features/oauth/components/OAuthClientForm.tsx +212 -0
- package/src/features/oauth/components/OAuthClientList.tsx +127 -0
- package/src/features/oauth/components/OAuthClientSecretDisplay.tsx +127 -0
- package/src/features/oauth/components/OAuthRedirectUriInput.tsx +152 -0
- package/src/features/oauth/components/OAuthScopeSelector.tsx +123 -0
- package/src/features/oauth/components/consent/OAuthConsentActions.tsx +41 -0
- package/src/features/oauth/components/consent/OAuthConsentHeader.tsx +51 -0
- package/src/features/oauth/components/consent/OAuthConsentScreen.tsx +142 -0
- package/src/features/oauth/components/consent/OAuthScopeList.tsx +72 -0
- package/src/features/oauth/components/consent/index.ts +4 -0
- package/src/features/oauth/components/index.ts +8 -0
- package/src/features/oauth/data/index.ts +2 -0
- package/src/features/oauth/data/oauth.service.ts +191 -0
- package/src/features/oauth/data/oauth.ts +87 -0
- package/src/features/oauth/hooks/index.ts +3 -0
- package/src/features/oauth/hooks/useOAuthClient.ts +161 -0
- package/src/features/oauth/hooks/useOAuthClients.ts +111 -0
- package/src/features/oauth/hooks/useOAuthConsent.ts +125 -0
- package/src/features/oauth/index.ts +6 -0
- package/src/features/oauth/interfaces/index.ts +1 -0
- package/src/features/oauth/interfaces/oauth.interface.ts +175 -0
- package/src/features/oauth/oauth.module.ts +9 -0
- package/dist/chunk-5U4NJJOF.mjs.map +0 -1
- package/dist/chunk-EJALOG7L.js.map +0 -1
- package/dist/chunk-H5JZ5E7M.mjs.map +0 -1
- package/dist/chunk-NQVPCNRS.js.map +0 -1
- /package/dist/{BlockNoteEditor-TJNLCNIP.mjs.map → BlockNoteEditor-UNVKGZ2G.mjs.map} +0 -0
|
@@ -13,13 +13,17 @@ import {
|
|
|
13
13
|
useI18nTranslations
|
|
14
14
|
} from "./chunk-GR4QPP36.mjs";
|
|
15
15
|
import {
|
|
16
|
+
AVAILABLE_OAUTH_SCOPES,
|
|
16
17
|
AuthService,
|
|
17
18
|
ClientAbstractService,
|
|
18
19
|
CompanyService,
|
|
19
20
|
ContentService,
|
|
21
|
+
DEFAULT_GRANT_TYPES,
|
|
20
22
|
FeatureService,
|
|
21
23
|
Modules,
|
|
22
24
|
NotificationService,
|
|
25
|
+
OAUTH_SCOPE_DISPLAY,
|
|
26
|
+
OAuthService,
|
|
23
27
|
PushService,
|
|
24
28
|
RehydrationFactory,
|
|
25
29
|
RoleService,
|
|
@@ -32,7 +36,7 @@ import {
|
|
|
32
36
|
rehydrate,
|
|
33
37
|
useComposedRefs,
|
|
34
38
|
useIsMobile
|
|
35
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-LNBT2YPZ.mjs";
|
|
36
40
|
import {
|
|
37
41
|
JsonApiContext
|
|
38
42
|
} from "./chunk-VOXD3ZLY.mjs";
|
|
@@ -10962,7 +10966,7 @@ __name(AllowedUsersDetails, "AllowedUsersDetails");
|
|
|
10962
10966
|
import dynamic from "next/dynamic";
|
|
10963
10967
|
import React15 from "react";
|
|
10964
10968
|
import { jsx as jsx121 } from "react/jsx-runtime";
|
|
10965
|
-
var BlockNoteEditor = dynamic(() => import("./BlockNoteEditor-
|
|
10969
|
+
var BlockNoteEditor = dynamic(() => import("./BlockNoteEditor-UNVKGZ2G.mjs"), {
|
|
10966
10970
|
ssr: false
|
|
10967
10971
|
});
|
|
10968
10972
|
var BlockNoteEditorContainer = React15.memo(/* @__PURE__ */ __name(function EditorContainer(props) {
|
|
@@ -11717,6 +11721,294 @@ var useContentTableStructure = /* @__PURE__ */ __name((params) => {
|
|
|
11717
11721
|
return useMemo17(() => ({ data: tableData, columns }), [tableData, columns]);
|
|
11718
11722
|
}, "useContentTableStructure");
|
|
11719
11723
|
|
|
11724
|
+
// src/features/oauth/hooks/useOAuthClients.ts
|
|
11725
|
+
import { useAtom as useAtom3, useSetAtom } from "jotai";
|
|
11726
|
+
import { useCallback as useCallback16, useEffect as useEffect34 } from "react";
|
|
11727
|
+
|
|
11728
|
+
// src/features/oauth/atoms/oauth.atoms.ts
|
|
11729
|
+
import { atom } from "jotai";
|
|
11730
|
+
import { atomFamily } from "jotai-family";
|
|
11731
|
+
var oauthClientsAtom = atom([]);
|
|
11732
|
+
var oauthClientsLoadingAtom = atom(false);
|
|
11733
|
+
var oauthClientsErrorAtom = atom(null);
|
|
11734
|
+
var oauthClientByIdAtom = atomFamily(
|
|
11735
|
+
(clientId) => atom((get) => {
|
|
11736
|
+
const clients = get(oauthClientsAtom);
|
|
11737
|
+
return clients.find((c) => c.clientId === clientId || c.id === clientId);
|
|
11738
|
+
})
|
|
11739
|
+
);
|
|
11740
|
+
var oauthNewClientSecretAtom = atom(null);
|
|
11741
|
+
var oauthNewClientIdAtom = atom(null);
|
|
11742
|
+
var oauthConsentLoadingAtom = atom(false);
|
|
11743
|
+
var oauthConsentErrorAtom = atom(null);
|
|
11744
|
+
var setNewClientSecretAtom = atom(null, (get, set, value) => {
|
|
11745
|
+
if (value === null) {
|
|
11746
|
+
set(oauthNewClientSecretAtom, null);
|
|
11747
|
+
set(oauthNewClientIdAtom, null);
|
|
11748
|
+
} else {
|
|
11749
|
+
set(oauthNewClientSecretAtom, value.secret);
|
|
11750
|
+
set(oauthNewClientIdAtom, value.clientId);
|
|
11751
|
+
}
|
|
11752
|
+
});
|
|
11753
|
+
var clearNewClientSecretAtom = atom(null, (get, set) => {
|
|
11754
|
+
set(oauthNewClientSecretAtom, null);
|
|
11755
|
+
set(oauthNewClientIdAtom, null);
|
|
11756
|
+
});
|
|
11757
|
+
var setOAuthClientsAtom = atom(null, (get, set, clients) => {
|
|
11758
|
+
set(oauthClientsAtom, clients);
|
|
11759
|
+
});
|
|
11760
|
+
var addOAuthClientAtom = atom(null, (get, set, client) => {
|
|
11761
|
+
const clients = get(oauthClientsAtom);
|
|
11762
|
+
set(oauthClientsAtom, [...clients, client]);
|
|
11763
|
+
});
|
|
11764
|
+
var updateOAuthClientAtom = atom(null, (get, set, updatedClient) => {
|
|
11765
|
+
const clients = get(oauthClientsAtom);
|
|
11766
|
+
const index = clients.findIndex((c) => c.id === updatedClient.id || c.clientId === updatedClient.clientId);
|
|
11767
|
+
if (index !== -1) {
|
|
11768
|
+
const newClients = [...clients];
|
|
11769
|
+
newClients[index] = updatedClient;
|
|
11770
|
+
set(oauthClientsAtom, newClients);
|
|
11771
|
+
}
|
|
11772
|
+
});
|
|
11773
|
+
var removeOAuthClientAtom = atom(null, (get, set, clientId) => {
|
|
11774
|
+
const clients = get(oauthClientsAtom);
|
|
11775
|
+
set(
|
|
11776
|
+
oauthClientsAtom,
|
|
11777
|
+
clients.filter((c) => c.id !== clientId && c.clientId !== clientId)
|
|
11778
|
+
);
|
|
11779
|
+
});
|
|
11780
|
+
|
|
11781
|
+
// src/features/oauth/hooks/useOAuthClients.ts
|
|
11782
|
+
function useOAuthClients() {
|
|
11783
|
+
const [clients, setClients] = useAtom3(oauthClientsAtom);
|
|
11784
|
+
const [isLoading, setIsLoading] = useAtom3(oauthClientsLoadingAtom);
|
|
11785
|
+
const [error, setError] = useAtom3(oauthClientsErrorAtom);
|
|
11786
|
+
const addClient = useSetAtom(addOAuthClientAtom);
|
|
11787
|
+
const setNewClientSecret = useSetAtom(setNewClientSecretAtom);
|
|
11788
|
+
const fetchClients = useCallback16(async () => {
|
|
11789
|
+
setIsLoading(true);
|
|
11790
|
+
setError(null);
|
|
11791
|
+
try {
|
|
11792
|
+
const fetchedClients = await OAuthService.listClients();
|
|
11793
|
+
setClients(fetchedClients);
|
|
11794
|
+
} catch (err) {
|
|
11795
|
+
console.error("[useOAuthClients] Failed to fetch clients:", err);
|
|
11796
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch OAuth clients"));
|
|
11797
|
+
} finally {
|
|
11798
|
+
setIsLoading(false);
|
|
11799
|
+
}
|
|
11800
|
+
}, [setClients, setIsLoading, setError]);
|
|
11801
|
+
useEffect34(() => {
|
|
11802
|
+
fetchClients();
|
|
11803
|
+
}, [fetchClients]);
|
|
11804
|
+
const createClient = useCallback16(
|
|
11805
|
+
async (data) => {
|
|
11806
|
+
setIsLoading(true);
|
|
11807
|
+
setError(null);
|
|
11808
|
+
try {
|
|
11809
|
+
const result = await OAuthService.createClient(data);
|
|
11810
|
+
addClient(result.client);
|
|
11811
|
+
if (result.clientSecret) {
|
|
11812
|
+
setNewClientSecret({
|
|
11813
|
+
clientId: result.client.clientId,
|
|
11814
|
+
secret: result.clientSecret
|
|
11815
|
+
});
|
|
11816
|
+
}
|
|
11817
|
+
return result;
|
|
11818
|
+
} catch (err) {
|
|
11819
|
+
console.error("[useOAuthClients] Failed to create client:", err);
|
|
11820
|
+
const error2 = err instanceof Error ? err : new Error("Failed to create OAuth client");
|
|
11821
|
+
setError(error2);
|
|
11822
|
+
throw error2;
|
|
11823
|
+
} finally {
|
|
11824
|
+
setIsLoading(false);
|
|
11825
|
+
}
|
|
11826
|
+
},
|
|
11827
|
+
[addClient, setNewClientSecret, setIsLoading, setError]
|
|
11828
|
+
);
|
|
11829
|
+
return {
|
|
11830
|
+
clients,
|
|
11831
|
+
isLoading,
|
|
11832
|
+
error,
|
|
11833
|
+
refetch: fetchClients,
|
|
11834
|
+
createClient
|
|
11835
|
+
};
|
|
11836
|
+
}
|
|
11837
|
+
__name(useOAuthClients, "useOAuthClients");
|
|
11838
|
+
|
|
11839
|
+
// src/features/oauth/hooks/useOAuthClient.ts
|
|
11840
|
+
import { useAtomValue as useAtomValue2, useSetAtom as useSetAtom2 } from "jotai";
|
|
11841
|
+
import { useCallback as useCallback17, useEffect as useEffect35, useState as useState41 } from "react";
|
|
11842
|
+
function useOAuthClient(clientId) {
|
|
11843
|
+
const storedClient = useAtomValue2(oauthClientByIdAtom(clientId));
|
|
11844
|
+
const updateClientInStore = useSetAtom2(updateOAuthClientAtom);
|
|
11845
|
+
const removeClientFromStore = useSetAtom2(removeOAuthClientAtom);
|
|
11846
|
+
const setNewClientSecret = useSetAtom2(setNewClientSecretAtom);
|
|
11847
|
+
const [fetchedClient, setFetchedClient] = useState41(null);
|
|
11848
|
+
const [isLoading, setIsLoading] = useState41(false);
|
|
11849
|
+
const [error, setError] = useState41(null);
|
|
11850
|
+
const client = storedClient || fetchedClient;
|
|
11851
|
+
const fetchClient = useCallback17(async () => {
|
|
11852
|
+
if (!clientId) return;
|
|
11853
|
+
setIsLoading(true);
|
|
11854
|
+
setError(null);
|
|
11855
|
+
try {
|
|
11856
|
+
const fetched = await OAuthService.getClient({ clientId });
|
|
11857
|
+
setFetchedClient(fetched);
|
|
11858
|
+
} catch (err) {
|
|
11859
|
+
console.error("[useOAuthClient] Failed to fetch client:", err);
|
|
11860
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch OAuth client"));
|
|
11861
|
+
} finally {
|
|
11862
|
+
setIsLoading(false);
|
|
11863
|
+
}
|
|
11864
|
+
}, [clientId]);
|
|
11865
|
+
useEffect35(() => {
|
|
11866
|
+
if (!storedClient && clientId) {
|
|
11867
|
+
fetchClient();
|
|
11868
|
+
}
|
|
11869
|
+
}, [storedClient, clientId, fetchClient]);
|
|
11870
|
+
const update = useCallback17(
|
|
11871
|
+
async (data) => {
|
|
11872
|
+
if (!clientId) throw new Error("No client ID");
|
|
11873
|
+
setIsLoading(true);
|
|
11874
|
+
setError(null);
|
|
11875
|
+
try {
|
|
11876
|
+
const updated = await OAuthService.updateClient({ clientId, data });
|
|
11877
|
+
updateClientInStore(updated);
|
|
11878
|
+
setFetchedClient(updated);
|
|
11879
|
+
} catch (err) {
|
|
11880
|
+
console.error("[useOAuthClient] Failed to update client:", err);
|
|
11881
|
+
const error2 = err instanceof Error ? err : new Error("Failed to update OAuth client");
|
|
11882
|
+
setError(error2);
|
|
11883
|
+
throw error2;
|
|
11884
|
+
} finally {
|
|
11885
|
+
setIsLoading(false);
|
|
11886
|
+
}
|
|
11887
|
+
},
|
|
11888
|
+
[clientId, updateClientInStore]
|
|
11889
|
+
);
|
|
11890
|
+
const deleteClient = useCallback17(async () => {
|
|
11891
|
+
if (!clientId) throw new Error("No client ID");
|
|
11892
|
+
setIsLoading(true);
|
|
11893
|
+
setError(null);
|
|
11894
|
+
try {
|
|
11895
|
+
await OAuthService.deleteClient({ clientId });
|
|
11896
|
+
removeClientFromStore(clientId);
|
|
11897
|
+
} catch (err) {
|
|
11898
|
+
console.error("[useOAuthClient] Failed to delete client:", err);
|
|
11899
|
+
const error2 = err instanceof Error ? err : new Error("Failed to delete OAuth client");
|
|
11900
|
+
setError(error2);
|
|
11901
|
+
throw error2;
|
|
11902
|
+
} finally {
|
|
11903
|
+
setIsLoading(false);
|
|
11904
|
+
}
|
|
11905
|
+
}, [clientId, removeClientFromStore]);
|
|
11906
|
+
const regenerateSecret = useCallback17(async () => {
|
|
11907
|
+
if (!clientId) throw new Error("No client ID");
|
|
11908
|
+
setIsLoading(true);
|
|
11909
|
+
setError(null);
|
|
11910
|
+
try {
|
|
11911
|
+
const result = await OAuthService.regenerateSecret({ clientId });
|
|
11912
|
+
setNewClientSecret({
|
|
11913
|
+
clientId,
|
|
11914
|
+
secret: result.clientSecret
|
|
11915
|
+
});
|
|
11916
|
+
return result.clientSecret;
|
|
11917
|
+
} catch (err) {
|
|
11918
|
+
console.error("[useOAuthClient] Failed to regenerate secret:", err);
|
|
11919
|
+
const error2 = err instanceof Error ? err : new Error("Failed to regenerate client secret");
|
|
11920
|
+
setError(error2);
|
|
11921
|
+
throw error2;
|
|
11922
|
+
} finally {
|
|
11923
|
+
setIsLoading(false);
|
|
11924
|
+
}
|
|
11925
|
+
}, [clientId, setNewClientSecret]);
|
|
11926
|
+
return {
|
|
11927
|
+
client,
|
|
11928
|
+
isLoading,
|
|
11929
|
+
error,
|
|
11930
|
+
update,
|
|
11931
|
+
deleteClient,
|
|
11932
|
+
regenerateSecret,
|
|
11933
|
+
refetch: fetchClient
|
|
11934
|
+
};
|
|
11935
|
+
}
|
|
11936
|
+
__name(useOAuthClient, "useOAuthClient");
|
|
11937
|
+
|
|
11938
|
+
// src/features/oauth/hooks/useOAuthConsent.ts
|
|
11939
|
+
import { useCallback as useCallback18, useEffect as useEffect36, useState as useState42 } from "react";
|
|
11940
|
+
function useOAuthConsent(params) {
|
|
11941
|
+
const [clientInfo, setClientInfo] = useState42(null);
|
|
11942
|
+
const [isLoading, setIsLoading] = useState42(true);
|
|
11943
|
+
const [error, setError] = useState42(null);
|
|
11944
|
+
const [isSubmitting, setIsSubmitting] = useState42(false);
|
|
11945
|
+
useEffect36(() => {
|
|
11946
|
+
const fetchInfo = /* @__PURE__ */ __name(async () => {
|
|
11947
|
+
if (!params.clientId || !params.redirectUri || !params.scope) {
|
|
11948
|
+
setError(new Error("Missing required authorization parameters"));
|
|
11949
|
+
setIsLoading(false);
|
|
11950
|
+
return;
|
|
11951
|
+
}
|
|
11952
|
+
setIsLoading(true);
|
|
11953
|
+
setError(null);
|
|
11954
|
+
try {
|
|
11955
|
+
const info = await OAuthService.getAuthorizationInfo(params);
|
|
11956
|
+
setClientInfo(info);
|
|
11957
|
+
} catch (err) {
|
|
11958
|
+
console.error("[useOAuthConsent] Failed to fetch authorization info:", err);
|
|
11959
|
+
setError(err instanceof Error ? err : new Error("Failed to load authorization info"));
|
|
11960
|
+
} finally {
|
|
11961
|
+
setIsLoading(false);
|
|
11962
|
+
}
|
|
11963
|
+
}, "fetchInfo");
|
|
11964
|
+
fetchInfo();
|
|
11965
|
+
}, [
|
|
11966
|
+
params.clientId,
|
|
11967
|
+
params.redirectUri,
|
|
11968
|
+
params.scope,
|
|
11969
|
+
params.state,
|
|
11970
|
+
params.codeChallenge,
|
|
11971
|
+
params.codeChallengeMethod
|
|
11972
|
+
]);
|
|
11973
|
+
const approve = useCallback18(async () => {
|
|
11974
|
+
setIsSubmitting(true);
|
|
11975
|
+
setError(null);
|
|
11976
|
+
try {
|
|
11977
|
+
const result = await OAuthService.approveAuthorization(params);
|
|
11978
|
+
if (result.redirectUrl) {
|
|
11979
|
+
window.location.href = result.redirectUrl;
|
|
11980
|
+
}
|
|
11981
|
+
} catch (err) {
|
|
11982
|
+
console.error("[useOAuthConsent] Failed to approve authorization:", err);
|
|
11983
|
+
setError(err instanceof Error ? err : new Error("Failed to approve authorization"));
|
|
11984
|
+
setIsSubmitting(false);
|
|
11985
|
+
}
|
|
11986
|
+
}, [params]);
|
|
11987
|
+
const deny = useCallback18(async () => {
|
|
11988
|
+
setIsSubmitting(true);
|
|
11989
|
+
setError(null);
|
|
11990
|
+
try {
|
|
11991
|
+
const result = await OAuthService.denyAuthorization(params);
|
|
11992
|
+
if (result.redirectUrl) {
|
|
11993
|
+
window.location.href = result.redirectUrl;
|
|
11994
|
+
}
|
|
11995
|
+
} catch (err) {
|
|
11996
|
+
console.error("[useOAuthConsent] Failed to deny authorization:", err);
|
|
11997
|
+
setError(err instanceof Error ? err : new Error("Failed to deny authorization"));
|
|
11998
|
+
setIsSubmitting(false);
|
|
11999
|
+
}
|
|
12000
|
+
}, [params]);
|
|
12001
|
+
return {
|
|
12002
|
+
clientInfo,
|
|
12003
|
+
isLoading,
|
|
12004
|
+
error,
|
|
12005
|
+
approve,
|
|
12006
|
+
deny,
|
|
12007
|
+
isSubmitting
|
|
12008
|
+
};
|
|
12009
|
+
}
|
|
12010
|
+
__name(useOAuthConsent, "useOAuthConsent");
|
|
12011
|
+
|
|
11720
12012
|
// src/client/index.ts
|
|
11721
12013
|
registerTableGenerator("roles", useRoleTableStructure);
|
|
11722
12014
|
registerTableGenerator("users", useUserTableStructure);
|
|
@@ -11730,17 +12022,17 @@ import { memo, useMemo as useMemo18 } from "react";
|
|
|
11730
12022
|
// src/components/tables/ContentTableSearch.tsx
|
|
11731
12023
|
import { RefreshCw, Search, X } from "lucide-react";
|
|
11732
12024
|
import { useTranslations as useTranslations45 } from "next-intl";
|
|
11733
|
-
import { useCallback as
|
|
12025
|
+
import { useCallback as useCallback19, useEffect as useEffect37, useRef as useRef16, useState as useState43 } from "react";
|
|
11734
12026
|
import { jsx as jsx133, jsxs as jsxs76 } from "react/jsx-runtime";
|
|
11735
12027
|
function ContentTableSearch({ data }) {
|
|
11736
12028
|
const t = useTranslations45();
|
|
11737
12029
|
const searchTermRef = useRef16("");
|
|
11738
12030
|
const inputRef = useRef16(null);
|
|
11739
|
-
const [searchTerm, setSearchTerm] =
|
|
11740
|
-
const [isFocused, setIsFocused] =
|
|
11741
|
-
const [isSearching, setIsSearching] =
|
|
12031
|
+
const [searchTerm, setSearchTerm] = useState43("");
|
|
12032
|
+
const [isFocused, setIsFocused] = useState43(false);
|
|
12033
|
+
const [isSearching, setIsSearching] = useState43(false);
|
|
11742
12034
|
const isExpanded = isFocused || searchTerm.length > 0;
|
|
11743
|
-
const search =
|
|
12035
|
+
const search = useCallback19(
|
|
11744
12036
|
async (searchedTerm) => {
|
|
11745
12037
|
try {
|
|
11746
12038
|
if (searchedTerm === searchTermRef.current) return;
|
|
@@ -11753,7 +12045,7 @@ function ContentTableSearch({ data }) {
|
|
|
11753
12045
|
[searchTermRef, data]
|
|
11754
12046
|
);
|
|
11755
12047
|
const updateSearchTerm = useDebounce(search, 500);
|
|
11756
|
-
|
|
12048
|
+
useEffect37(() => {
|
|
11757
12049
|
setIsSearching(true);
|
|
11758
12050
|
updateSearchTerm(searchTerm);
|
|
11759
12051
|
}, [updateSearchTerm, searchTerm]);
|
|
@@ -11905,13 +12197,13 @@ var ContentListTable = memo(/* @__PURE__ */ __name(function ContentListTable2(pr
|
|
|
11905
12197
|
import Image9 from "next/image";
|
|
11906
12198
|
|
|
11907
12199
|
// src/features/auth/contexts/AuthContext.tsx
|
|
11908
|
-
import { createContext as createContext14, useContext as useContext15, useMemo as useMemo19, useState as
|
|
12200
|
+
import { createContext as createContext14, useContext as useContext15, useMemo as useMemo19, useState as useState45 } from "react";
|
|
11909
12201
|
|
|
11910
12202
|
// src/features/auth/components/forms/Register.tsx
|
|
11911
12203
|
import { zodResolver as zodResolver5 } from "@hookform/resolvers/zod";
|
|
11912
12204
|
import { useTranslations as useTranslations46 } from "next-intl";
|
|
11913
12205
|
import Image8 from "next/image";
|
|
11914
|
-
import { useState as
|
|
12206
|
+
import { useState as useState44 } from "react";
|
|
11915
12207
|
import { useForm as useForm5 } from "react-hook-form";
|
|
11916
12208
|
import { v4 as v44 } from "uuid";
|
|
11917
12209
|
import { z as z5 } from "zod";
|
|
@@ -11919,7 +12211,7 @@ import { Fragment as Fragment20, jsx as jsx135, jsxs as jsxs78 } from "react/jsx
|
|
|
11919
12211
|
function Register() {
|
|
11920
12212
|
const t = useTranslations46();
|
|
11921
12213
|
const { setComponentType } = useAuthContext();
|
|
11922
|
-
const [showConfirmation, setShowConfirmation] =
|
|
12214
|
+
const [showConfirmation, setShowConfirmation] = useState44(false);
|
|
11923
12215
|
const formSchema = z5.object({
|
|
11924
12216
|
company: z5.string().min(1, {
|
|
11925
12217
|
message: t(`generic.errors.missing_company_name`)
|
|
@@ -12043,8 +12335,8 @@ var AuthContextProvider = /* @__PURE__ */ __name(({
|
|
|
12043
12335
|
initialComponentType,
|
|
12044
12336
|
initialParams
|
|
12045
12337
|
}) => {
|
|
12046
|
-
const [componentType, setComponentType] =
|
|
12047
|
-
const [params, setParams] =
|
|
12338
|
+
const [componentType, setComponentType] = useState45(initialComponentType);
|
|
12339
|
+
const [params, setParams] = useState45(initialParams);
|
|
12048
12340
|
const activeComponent = useMemo19(() => {
|
|
12049
12341
|
if (componentType === void 0) return null;
|
|
12050
12342
|
switch (componentType) {
|
|
@@ -12137,17 +12429,17 @@ __name(LandingComponent, "LandingComponent");
|
|
|
12137
12429
|
import { zodResolver as zodResolver6 } from "@hookform/resolvers/zod";
|
|
12138
12430
|
import { useTranslations as useTranslations48 } from "next-intl";
|
|
12139
12431
|
import Image11 from "next/image";
|
|
12140
|
-
import { useEffect as
|
|
12432
|
+
import { useEffect as useEffect38, useState as useState46 } from "react";
|
|
12141
12433
|
import { useForm as useForm6 } from "react-hook-form";
|
|
12142
12434
|
import { toast as toast7 } from "sonner";
|
|
12143
12435
|
import { z as z6 } from "zod";
|
|
12144
12436
|
import { Fragment as Fragment22, jsx as jsx139, jsxs as jsxs80 } from "react/jsx-runtime";
|
|
12145
12437
|
function AcceptInvitation() {
|
|
12146
12438
|
const { setComponentType, params, setParams } = useAuthContext();
|
|
12147
|
-
const [showConfirmation, setShowConfirmation] =
|
|
12148
|
-
const [error, setError] =
|
|
12439
|
+
const [showConfirmation, setShowConfirmation] = useState46(false);
|
|
12440
|
+
const [error, setError] = useState46(void 0);
|
|
12149
12441
|
const t = useTranslations48();
|
|
12150
|
-
|
|
12442
|
+
useEffect38(() => {
|
|
12151
12443
|
async function validateCode(code) {
|
|
12152
12444
|
try {
|
|
12153
12445
|
const payload = {
|
|
@@ -12240,15 +12532,15 @@ __name(AcceptInvitation, "AcceptInvitation");
|
|
|
12240
12532
|
// src/features/auth/components/forms/ActivateAccount.tsx
|
|
12241
12533
|
import { useTranslations as useTranslations49 } from "next-intl";
|
|
12242
12534
|
import Image12 from "next/image";
|
|
12243
|
-
import { useEffect as
|
|
12535
|
+
import { useEffect as useEffect39, useState as useState47 } from "react";
|
|
12244
12536
|
import { toast as toast8 } from "sonner";
|
|
12245
12537
|
import { Fragment as Fragment23, jsx as jsx140, jsxs as jsxs81 } from "react/jsx-runtime";
|
|
12246
12538
|
function ActivateAccount() {
|
|
12247
12539
|
const { setComponentType, params, setParams } = useAuthContext();
|
|
12248
|
-
const [showConfirmation, setShowConfirmation] =
|
|
12249
|
-
const [error, setError] =
|
|
12540
|
+
const [showConfirmation, setShowConfirmation] = useState47(false);
|
|
12541
|
+
const [error, setError] = useState47(void 0);
|
|
12250
12542
|
const t = useTranslations49();
|
|
12251
|
-
|
|
12543
|
+
useEffect39(() => {
|
|
12252
12544
|
async function ActivateAccount2(code) {
|
|
12253
12545
|
try {
|
|
12254
12546
|
const payload = {
|
|
@@ -12289,12 +12581,12 @@ function ActivateAccount() {
|
|
|
12289
12581
|
__name(ActivateAccount, "ActivateAccount");
|
|
12290
12582
|
|
|
12291
12583
|
// src/features/auth/components/forms/Cookies.tsx
|
|
12292
|
-
import { useEffect as
|
|
12584
|
+
import { useEffect as useEffect40, useState as useState48 } from "react";
|
|
12293
12585
|
function Cookies({ dehydratedAuth, page }) {
|
|
12294
12586
|
const { setUser } = useCurrentUserContext();
|
|
12295
12587
|
const router = useI18nRouter();
|
|
12296
|
-
const [hasSaved, setHasSaved] =
|
|
12297
|
-
|
|
12588
|
+
const [hasSaved, setHasSaved] = useState48(false);
|
|
12589
|
+
useEffect40(() => {
|
|
12298
12590
|
if (hasSaved) return;
|
|
12299
12591
|
async function saveTokenOnServer() {
|
|
12300
12592
|
await AuthService.saveToken({ dehydratedAuth });
|
|
@@ -12317,14 +12609,14 @@ __name(Cookies, "Cookies");
|
|
|
12317
12609
|
import { zodResolver as zodResolver7 } from "@hookform/resolvers/zod";
|
|
12318
12610
|
import { useTranslations as useTranslations50 } from "next-intl";
|
|
12319
12611
|
import Image13 from "next/image";
|
|
12320
|
-
import { useState as
|
|
12612
|
+
import { useState as useState49 } from "react";
|
|
12321
12613
|
import { useForm as useForm7 } from "react-hook-form";
|
|
12322
12614
|
import { z as z7 } from "zod";
|
|
12323
12615
|
import { Fragment as Fragment24, jsx as jsx141, jsxs as jsxs82 } from "react/jsx-runtime";
|
|
12324
12616
|
function ForgotPassword() {
|
|
12325
12617
|
const t = useTranslations50();
|
|
12326
12618
|
const { setComponentType } = useAuthContext();
|
|
12327
|
-
const [showConfirmation, setShowConfirmation] =
|
|
12619
|
+
const [showConfirmation, setShowConfirmation] = useState49(false);
|
|
12328
12620
|
const formSchema = z7.object({
|
|
12329
12621
|
email: z7.string().email({
|
|
12330
12622
|
message: t(`generic.errors.invalid_email`)
|
|
@@ -12488,11 +12780,11 @@ function Login() {
|
|
|
12488
12780
|
__name(Login, "Login");
|
|
12489
12781
|
|
|
12490
12782
|
// src/features/auth/components/forms/Logout.tsx
|
|
12491
|
-
import { useEffect as
|
|
12783
|
+
import { useEffect as useEffect41 } from "react";
|
|
12492
12784
|
import { Fragment as Fragment26, jsx as jsx143 } from "react/jsx-runtime";
|
|
12493
12785
|
function Logout() {
|
|
12494
12786
|
const generateUrl = usePageUrlGenerator();
|
|
12495
|
-
|
|
12787
|
+
useEffect41(() => {
|
|
12496
12788
|
const logOut = /* @__PURE__ */ __name(async () => {
|
|
12497
12789
|
await AuthService.logout();
|
|
12498
12790
|
window.location.href = generateUrl({ page: `/` });
|
|
@@ -12505,7 +12797,7 @@ __name(Logout, "Logout");
|
|
|
12505
12797
|
|
|
12506
12798
|
// src/features/auth/components/forms/RefreshUser.tsx
|
|
12507
12799
|
import { deleteCookie as deleteCookie2, getCookie as getCookie2 } from "cookies-next";
|
|
12508
|
-
import { useEffect as
|
|
12800
|
+
import { useEffect as useEffect42 } from "react";
|
|
12509
12801
|
function RefreshUser() {
|
|
12510
12802
|
const { setUser } = useCurrentUserContext();
|
|
12511
12803
|
const loadFullUser = /* @__PURE__ */ __name(async () => {
|
|
@@ -12526,7 +12818,7 @@ function RefreshUser() {
|
|
|
12526
12818
|
deleteCookie2("reloadData");
|
|
12527
12819
|
}
|
|
12528
12820
|
}, "loadFullUser");
|
|
12529
|
-
|
|
12821
|
+
useEffect42(() => {
|
|
12530
12822
|
const reloadData = getCookie2("reloadData");
|
|
12531
12823
|
if (reloadData !== void 0) loadFullUser();
|
|
12532
12824
|
}, []);
|
|
@@ -12538,17 +12830,17 @@ __name(RefreshUser, "RefreshUser");
|
|
|
12538
12830
|
import { zodResolver as zodResolver9 } from "@hookform/resolvers/zod";
|
|
12539
12831
|
import { useTranslations as useTranslations52 } from "next-intl";
|
|
12540
12832
|
import Image15 from "next/image";
|
|
12541
|
-
import { useEffect as
|
|
12833
|
+
import { useEffect as useEffect43, useState as useState50 } from "react";
|
|
12542
12834
|
import { useForm as useForm9 } from "react-hook-form";
|
|
12543
12835
|
import { toast as toast9 } from "sonner";
|
|
12544
12836
|
import { z as z9 } from "zod";
|
|
12545
12837
|
import { Fragment as Fragment27, jsx as jsx144, jsxs as jsxs84 } from "react/jsx-runtime";
|
|
12546
12838
|
function ResetPassword() {
|
|
12547
12839
|
const { setComponentType, params, setParams } = useAuthContext();
|
|
12548
|
-
const [showConfirmation, setShowConfirmation] =
|
|
12549
|
-
const [error, setError] =
|
|
12840
|
+
const [showConfirmation, setShowConfirmation] = useState50(false);
|
|
12841
|
+
const [error, setError] = useState50(void 0);
|
|
12550
12842
|
const t = useTranslations52();
|
|
12551
|
-
|
|
12843
|
+
useEffect43(() => {
|
|
12552
12844
|
async function validateResetPasswordCode(code) {
|
|
12553
12845
|
try {
|
|
12554
12846
|
const payload = {
|
|
@@ -12830,7 +13122,7 @@ __name(NotificationsListContainer, "NotificationsListContainer");
|
|
|
12830
13122
|
// src/features/notification/components/modals/NotificationModal.tsx
|
|
12831
13123
|
import { BellIcon } from "lucide-react";
|
|
12832
13124
|
import { useTranslations as useTranslations58 } from "next-intl";
|
|
12833
|
-
import { Fragment as Fragment29, useCallback as
|
|
13125
|
+
import { Fragment as Fragment29, useCallback as useCallback20, useEffect as useEffect44, useMemo as useMemo20, useRef as useRef17, useState as useState51 } from "react";
|
|
12834
13126
|
import { toast as toast10 } from "sonner";
|
|
12835
13127
|
import { jsx as jsx151, jsxs as jsxs89 } from "react/jsx-runtime";
|
|
12836
13128
|
function NotificationModalContent({ isOpen, setIsOpen }) {
|
|
@@ -12850,14 +13142,14 @@ function NotificationModalContent({ isOpen, setIsOpen }) {
|
|
|
12850
13142
|
const { socketNotifications, removeSocketNotification, clearSocketNotifications } = useSocketContext();
|
|
12851
13143
|
const t = useTranslations58();
|
|
12852
13144
|
const generateUrl = usePageUrlGenerator();
|
|
12853
|
-
const [newNotifications, setNewNotifications] =
|
|
13145
|
+
const [newNotifications, setNewNotifications] = useState51(false);
|
|
12854
13146
|
const preventAutoClose = useRef17(false);
|
|
12855
13147
|
const circuitBreakerRef = useRef17({
|
|
12856
13148
|
count: 0,
|
|
12857
13149
|
resetTime: 0,
|
|
12858
13150
|
isOpen: false
|
|
12859
13151
|
});
|
|
12860
|
-
const checkCircuitBreaker =
|
|
13152
|
+
const checkCircuitBreaker = useCallback20(() => {
|
|
12861
13153
|
const now = Date.now();
|
|
12862
13154
|
const breaker = circuitBreakerRef.current;
|
|
12863
13155
|
if (now > breaker.resetTime) {
|
|
@@ -12879,14 +13171,14 @@ function NotificationModalContent({ isOpen, setIsOpen }) {
|
|
|
12879
13171
|
unreadIds: unreadNotifications2.map((notif) => notif.id)
|
|
12880
13172
|
};
|
|
12881
13173
|
}, [notifications]);
|
|
12882
|
-
|
|
13174
|
+
useEffect44(() => {
|
|
12883
13175
|
setNewNotifications(unreadCount > 0);
|
|
12884
13176
|
}, [unreadCount]);
|
|
12885
|
-
|
|
13177
|
+
useEffect44(() => {
|
|
12886
13178
|
if (lastLoaded === 0) loadNotifications();
|
|
12887
13179
|
}, [lastLoaded, loadNotifications]);
|
|
12888
13180
|
const processSocketNotificationsRef = useRef17(null);
|
|
12889
|
-
const processSocketNotifications =
|
|
13181
|
+
const processSocketNotifications = useCallback20(() => {
|
|
12890
13182
|
if (socketNotifications.length === 0) {
|
|
12891
13183
|
return;
|
|
12892
13184
|
}
|
|
@@ -12925,7 +13217,7 @@ function NotificationModalContent({ isOpen, setIsOpen }) {
|
|
|
12925
13217
|
generateUrl,
|
|
12926
13218
|
checkCircuitBreaker
|
|
12927
13219
|
]);
|
|
12928
|
-
|
|
13220
|
+
useEffect44(() => {
|
|
12929
13221
|
if (processSocketNotificationsRef.current) {
|
|
12930
13222
|
clearTimeout(processSocketNotificationsRef.current);
|
|
12931
13223
|
}
|
|
@@ -13059,13 +13351,13 @@ __name(FormRoles, "FormRoles");
|
|
|
13059
13351
|
|
|
13060
13352
|
// src/features/role/components/forms/RemoveUserFromRole.tsx
|
|
13061
13353
|
import { useTranslations as useTranslations61 } from "next-intl";
|
|
13062
|
-
import { useEffect as
|
|
13354
|
+
import { useEffect as useEffect45, useState as useState52 } from "react";
|
|
13063
13355
|
import { Fragment as Fragment32, jsx as jsx156, jsxs as jsxs92 } from "react/jsx-runtime";
|
|
13064
13356
|
function RemoveUserFromRole({ role, user, refresh }) {
|
|
13065
|
-
const [open, setOpen] =
|
|
13066
|
-
const [canRemove, setCanRemove] =
|
|
13357
|
+
const [open, setOpen] = useState52(false);
|
|
13358
|
+
const [canRemove, setCanRemove] = useState52(false);
|
|
13067
13359
|
const t = useTranslations61();
|
|
13068
|
-
|
|
13360
|
+
useEffect45(() => {
|
|
13069
13361
|
async function checkCompanyAdminDeletability() {
|
|
13070
13362
|
const roleUsers = await UserService.findAllUsersByRole({
|
|
13071
13363
|
roleId: role.id
|
|
@@ -13135,14 +13427,14 @@ __name(RemoveUserFromRole, "RemoveUserFromRole");
|
|
|
13135
13427
|
// src/features/role/components/forms/UserRoleAdd.tsx
|
|
13136
13428
|
import { PlusCircle } from "lucide-react";
|
|
13137
13429
|
import { useTranslations as useTranslations62 } from "next-intl";
|
|
13138
|
-
import { useCallback as
|
|
13430
|
+
import { useCallback as useCallback21, useEffect as useEffect46, useRef as useRef18, useState as useState53 } from "react";
|
|
13139
13431
|
import { toast as toast11 } from "sonner";
|
|
13140
13432
|
import { Fragment as Fragment33, jsx as jsx157, jsxs as jsxs93 } from "react/jsx-runtime";
|
|
13141
13433
|
function UserRoleAdd({ user, refresh }) {
|
|
13142
|
-
const [open, setOpen] =
|
|
13434
|
+
const [open, setOpen] = useState53(false);
|
|
13143
13435
|
const inputRef = useRef18(null);
|
|
13144
|
-
const [searchTerm, setSearchTerm] =
|
|
13145
|
-
const [roles, setRoles] =
|
|
13436
|
+
const [searchTerm, setSearchTerm] = useState53("");
|
|
13437
|
+
const [roles, setRoles] = useState53([]);
|
|
13146
13438
|
const t = useTranslations62();
|
|
13147
13439
|
const addUserToRole = /* @__PURE__ */ __name(async (role) => {
|
|
13148
13440
|
await RoleService.addUserToRole({
|
|
@@ -13166,7 +13458,7 @@ function UserRoleAdd({ user, refresh }) {
|
|
|
13166
13458
|
);
|
|
13167
13459
|
refresh();
|
|
13168
13460
|
}, "addUserToRole");
|
|
13169
|
-
const searchRoles =
|
|
13461
|
+
const searchRoles = useCallback21(
|
|
13170
13462
|
async (term) => {
|
|
13171
13463
|
setRoles(
|
|
13172
13464
|
await RoleService.findAllRolesUserNotIn({
|
|
@@ -13178,10 +13470,10 @@ function UserRoleAdd({ user, refresh }) {
|
|
|
13178
13470
|
[searchTerm, user]
|
|
13179
13471
|
);
|
|
13180
13472
|
const updateSearchTerm = useDebounce(searchRoles, 500);
|
|
13181
|
-
|
|
13473
|
+
useEffect46(() => {
|
|
13182
13474
|
if (open) updateSearchTerm(searchTerm);
|
|
13183
13475
|
}, [open, searchTerm]);
|
|
13184
|
-
|
|
13476
|
+
useEffect46(() => {
|
|
13185
13477
|
if (open) searchRoles("");
|
|
13186
13478
|
}, [open]);
|
|
13187
13479
|
return /* @__PURE__ */ jsxs93(Fragment33, { children: [
|
|
@@ -13275,6 +13567,893 @@ function UserRolesList({ user }) {
|
|
|
13275
13567
|
}
|
|
13276
13568
|
__name(UserRolesList, "UserRolesList");
|
|
13277
13569
|
|
|
13570
|
+
// src/features/oauth/components/OAuthRedirectUriInput.tsx
|
|
13571
|
+
import { useCallback as useCallback22 } from "react";
|
|
13572
|
+
import { Plus, Trash2 } from "lucide-react";
|
|
13573
|
+
import { jsx as jsx160, jsxs as jsxs94 } from "react/jsx-runtime";
|
|
13574
|
+
function isValidRedirectUri(uri) {
|
|
13575
|
+
if (!uri.trim()) return false;
|
|
13576
|
+
if (uri.startsWith("http://localhost") || uri.startsWith("http://127.0.0.1")) {
|
|
13577
|
+
return true;
|
|
13578
|
+
}
|
|
13579
|
+
if (uri.startsWith("https://")) {
|
|
13580
|
+
try {
|
|
13581
|
+
new URL(uri);
|
|
13582
|
+
return true;
|
|
13583
|
+
} catch {
|
|
13584
|
+
return false;
|
|
13585
|
+
}
|
|
13586
|
+
}
|
|
13587
|
+
if (uri.includes("://")) {
|
|
13588
|
+
const schemeMatch = uri.match(/^([a-zA-Z][a-zA-Z0-9+.-]*):\/\//);
|
|
13589
|
+
return schemeMatch !== null;
|
|
13590
|
+
}
|
|
13591
|
+
return false;
|
|
13592
|
+
}
|
|
13593
|
+
__name(isValidRedirectUri, "isValidRedirectUri");
|
|
13594
|
+
function OAuthRedirectUriInput({
|
|
13595
|
+
value,
|
|
13596
|
+
onChange,
|
|
13597
|
+
error,
|
|
13598
|
+
disabled = false,
|
|
13599
|
+
label = "Redirect URIs"
|
|
13600
|
+
}) {
|
|
13601
|
+
const handleAdd = useCallback22(() => {
|
|
13602
|
+
onChange([...value, ""]);
|
|
13603
|
+
}, [value, onChange]);
|
|
13604
|
+
const handleRemove = useCallback22(
|
|
13605
|
+
(index) => {
|
|
13606
|
+
const newUris = value.filter((_, i) => i !== index);
|
|
13607
|
+
onChange(newUris.length > 0 ? newUris : [""]);
|
|
13608
|
+
},
|
|
13609
|
+
[value, onChange]
|
|
13610
|
+
);
|
|
13611
|
+
const handleChange = useCallback22(
|
|
13612
|
+
(index, newValue) => {
|
|
13613
|
+
const newUris = [...value];
|
|
13614
|
+
newUris[index] = newValue;
|
|
13615
|
+
onChange(newUris);
|
|
13616
|
+
},
|
|
13617
|
+
[value, onChange]
|
|
13618
|
+
);
|
|
13619
|
+
return /* @__PURE__ */ jsxs94("div", { className: "space-y-2", children: [
|
|
13620
|
+
/* @__PURE__ */ jsxs94(Label, { children: [
|
|
13621
|
+
label,
|
|
13622
|
+
" *"
|
|
13623
|
+
] }),
|
|
13624
|
+
/* @__PURE__ */ jsx160("p", { className: "text-sm text-muted-foreground", children: "Enter the URIs where users will be redirected after authorization. Use https:// for production, or custom schemes for mobile apps." }),
|
|
13625
|
+
/* @__PURE__ */ jsx160("div", { className: "space-y-2", children: value.map((uri, index) => {
|
|
13626
|
+
const isValid3 = !uri || isValidRedirectUri(uri);
|
|
13627
|
+
return /* @__PURE__ */ jsxs94("div", { className: "flex gap-2", children: [
|
|
13628
|
+
/* @__PURE__ */ jsxs94("div", { className: "flex-1", children: [
|
|
13629
|
+
/* @__PURE__ */ jsx160(
|
|
13630
|
+
Input,
|
|
13631
|
+
{
|
|
13632
|
+
value: uri,
|
|
13633
|
+
onChange: (e) => handleChange(index, e.target.value),
|
|
13634
|
+
placeholder: "https://example.com/callback or myapp://oauth",
|
|
13635
|
+
disabled,
|
|
13636
|
+
className: !isValid3 ? "border-destructive" : ""
|
|
13637
|
+
}
|
|
13638
|
+
),
|
|
13639
|
+
!isValid3 && /* @__PURE__ */ jsx160("p", { className: "text-xs text-destructive mt-1", children: "Must be https://, http://localhost, or a custom scheme (app://)" })
|
|
13640
|
+
] }),
|
|
13641
|
+
/* @__PURE__ */ jsx160(
|
|
13642
|
+
Button,
|
|
13643
|
+
{
|
|
13644
|
+
type: "button",
|
|
13645
|
+
variant: "ghost",
|
|
13646
|
+
size: "icon",
|
|
13647
|
+
onClick: () => handleRemove(index),
|
|
13648
|
+
disabled: disabled || value.length === 1,
|
|
13649
|
+
title: "Remove URI",
|
|
13650
|
+
children: /* @__PURE__ */ jsx160(Trash2, { className: "h-4 w-4" })
|
|
13651
|
+
}
|
|
13652
|
+
)
|
|
13653
|
+
] }, index);
|
|
13654
|
+
}) }),
|
|
13655
|
+
/* @__PURE__ */ jsxs94(
|
|
13656
|
+
Button,
|
|
13657
|
+
{
|
|
13658
|
+
type: "button",
|
|
13659
|
+
variant: "outline",
|
|
13660
|
+
size: "sm",
|
|
13661
|
+
onClick: handleAdd,
|
|
13662
|
+
disabled,
|
|
13663
|
+
className: "mt-2",
|
|
13664
|
+
children: [
|
|
13665
|
+
/* @__PURE__ */ jsx160(Plus, { className: "h-4 w-4 mr-2" }),
|
|
13666
|
+
"Add Redirect URI"
|
|
13667
|
+
]
|
|
13668
|
+
}
|
|
13669
|
+
),
|
|
13670
|
+
error && /* @__PURE__ */ jsx160("p", { className: "text-sm text-destructive", children: error })
|
|
13671
|
+
] });
|
|
13672
|
+
}
|
|
13673
|
+
__name(OAuthRedirectUriInput, "OAuthRedirectUriInput");
|
|
13674
|
+
|
|
13675
|
+
// src/features/oauth/components/OAuthScopeSelector.tsx
|
|
13676
|
+
import { useCallback as useCallback23 } from "react";
|
|
13677
|
+
import { jsx as jsx161, jsxs as jsxs95 } from "react/jsx-runtime";
|
|
13678
|
+
function OAuthScopeSelector({
|
|
13679
|
+
value,
|
|
13680
|
+
onChange,
|
|
13681
|
+
availableScopes = AVAILABLE_OAUTH_SCOPES,
|
|
13682
|
+
disabled = false,
|
|
13683
|
+
error,
|
|
13684
|
+
label = "Allowed Scopes"
|
|
13685
|
+
}) {
|
|
13686
|
+
const handleToggle = useCallback23(
|
|
13687
|
+
(scope, checked) => {
|
|
13688
|
+
if (checked) {
|
|
13689
|
+
onChange([...value, scope]);
|
|
13690
|
+
} else {
|
|
13691
|
+
onChange(value.filter((s) => s !== scope));
|
|
13692
|
+
}
|
|
13693
|
+
},
|
|
13694
|
+
[value, onChange]
|
|
13695
|
+
);
|
|
13696
|
+
const groupedScopes = availableScopes.reduce((acc, scope) => {
|
|
13697
|
+
const [category] = scope.scope.split(":");
|
|
13698
|
+
const groupName = category === scope.scope ? "General" : category;
|
|
13699
|
+
if (!acc[groupName]) {
|
|
13700
|
+
acc[groupName] = [];
|
|
13701
|
+
}
|
|
13702
|
+
acc[groupName].push(scope);
|
|
13703
|
+
return acc;
|
|
13704
|
+
}, {});
|
|
13705
|
+
return /* @__PURE__ */ jsxs95("div", { className: "space-y-4", children: [
|
|
13706
|
+
/* @__PURE__ */ jsxs95("div", { children: [
|
|
13707
|
+
/* @__PURE__ */ jsxs95(Label, { children: [
|
|
13708
|
+
label,
|
|
13709
|
+
" *"
|
|
13710
|
+
] }),
|
|
13711
|
+
/* @__PURE__ */ jsx161("p", { className: "text-sm text-muted-foreground", children: "Select the permissions your application needs." })
|
|
13712
|
+
] }),
|
|
13713
|
+
/* @__PURE__ */ jsx161("div", { className: "space-y-4", children: Object.entries(groupedScopes).map(([groupName, scopes]) => /* @__PURE__ */ jsxs95("div", { className: "space-y-2", children: [
|
|
13714
|
+
/* @__PURE__ */ jsx161("h4", { className: "text-sm font-medium capitalize", children: groupName }),
|
|
13715
|
+
/* @__PURE__ */ jsx161("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-2 pl-2", children: scopes.map((scopeInfo) => {
|
|
13716
|
+
const isChecked = value.includes(scopeInfo.scope);
|
|
13717
|
+
const isAdmin = scopeInfo.scope === "admin";
|
|
13718
|
+
return /* @__PURE__ */ jsxs95(
|
|
13719
|
+
"div",
|
|
13720
|
+
{
|
|
13721
|
+
className: `flex items-start space-x-3 p-2 rounded-md border ${isChecked ? "bg-primary/5 border-primary/20" : "border-transparent"} ${isAdmin ? "bg-destructive/5" : ""}`,
|
|
13722
|
+
children: [
|
|
13723
|
+
/* @__PURE__ */ jsx161(
|
|
13724
|
+
Checkbox,
|
|
13725
|
+
{
|
|
13726
|
+
id: `scope-${scopeInfo.scope}`,
|
|
13727
|
+
checked: isChecked,
|
|
13728
|
+
onCheckedChange: (checked) => handleToggle(scopeInfo.scope, checked === true),
|
|
13729
|
+
disabled
|
|
13730
|
+
}
|
|
13731
|
+
),
|
|
13732
|
+
/* @__PURE__ */ jsxs95("div", { className: "flex-1", children: [
|
|
13733
|
+
/* @__PURE__ */ jsxs95(
|
|
13734
|
+
Label,
|
|
13735
|
+
{
|
|
13736
|
+
htmlFor: `scope-${scopeInfo.scope}`,
|
|
13737
|
+
className: "text-sm font-medium cursor-pointer",
|
|
13738
|
+
children: [
|
|
13739
|
+
scopeInfo.name,
|
|
13740
|
+
isAdmin && /* @__PURE__ */ jsx161("span", { className: "ml-2 text-xs text-destructive", children: "(Dangerous)" })
|
|
13741
|
+
]
|
|
13742
|
+
}
|
|
13743
|
+
),
|
|
13744
|
+
/* @__PURE__ */ jsx161("p", { className: "text-xs text-muted-foreground", children: scopeInfo.description })
|
|
13745
|
+
] })
|
|
13746
|
+
]
|
|
13747
|
+
},
|
|
13748
|
+
scopeInfo.scope
|
|
13749
|
+
);
|
|
13750
|
+
}) })
|
|
13751
|
+
] }, groupName)) }),
|
|
13752
|
+
error && /* @__PURE__ */ jsx161("p", { className: "text-sm text-destructive", children: error })
|
|
13753
|
+
] });
|
|
13754
|
+
}
|
|
13755
|
+
__name(OAuthScopeSelector, "OAuthScopeSelector");
|
|
13756
|
+
|
|
13757
|
+
// src/features/oauth/components/OAuthClientSecretDisplay.tsx
|
|
13758
|
+
import { useState as useState54, useCallback as useCallback24 } from "react";
|
|
13759
|
+
import { Copy, Check, AlertTriangle } from "lucide-react";
|
|
13760
|
+
import { jsx as jsx162, jsxs as jsxs96 } from "react/jsx-runtime";
|
|
13761
|
+
function OAuthClientSecretDisplay({
|
|
13762
|
+
secret,
|
|
13763
|
+
onDismiss,
|
|
13764
|
+
open,
|
|
13765
|
+
clientName
|
|
13766
|
+
}) {
|
|
13767
|
+
const [copied, setCopied] = useState54(false);
|
|
13768
|
+
const handleCopy = useCallback24(async () => {
|
|
13769
|
+
try {
|
|
13770
|
+
await navigator.clipboard.writeText(secret);
|
|
13771
|
+
setCopied(true);
|
|
13772
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
13773
|
+
} catch (err) {
|
|
13774
|
+
console.error("Failed to copy to clipboard:", err);
|
|
13775
|
+
}
|
|
13776
|
+
}, [secret]);
|
|
13777
|
+
const handleDismiss = useCallback24(() => {
|
|
13778
|
+
setCopied(false);
|
|
13779
|
+
onDismiss();
|
|
13780
|
+
}, [onDismiss]);
|
|
13781
|
+
return /* @__PURE__ */ jsx162(Dialog, { open, onOpenChange: (isOpen) => !isOpen && handleDismiss(), children: /* @__PURE__ */ jsxs96(DialogContent, { className: "sm:max-w-md", children: [
|
|
13782
|
+
/* @__PURE__ */ jsxs96(DialogHeader, { children: [
|
|
13783
|
+
/* @__PURE__ */ jsxs96(DialogTitle, { className: "flex items-center gap-2", children: [
|
|
13784
|
+
/* @__PURE__ */ jsx162(AlertTriangle, { className: "h-5 w-5 text-warning" }),
|
|
13785
|
+
"Save Your Client Secret"
|
|
13786
|
+
] }),
|
|
13787
|
+
/* @__PURE__ */ jsx162(DialogDescription, { children: clientName ? `Your client secret for "${clientName}" is shown below.` : "Your client secret is shown below." })
|
|
13788
|
+
] }),
|
|
13789
|
+
/* @__PURE__ */ jsxs96(Alert, { variant: "destructive", className: "my-4", children: [
|
|
13790
|
+
/* @__PURE__ */ jsx162(AlertTriangle, { className: "h-4 w-4" }),
|
|
13791
|
+
/* @__PURE__ */ jsxs96(AlertDescription, { children: [
|
|
13792
|
+
/* @__PURE__ */ jsx162("strong", { children: "This is the only time your client secret will be displayed." }),
|
|
13793
|
+
/* @__PURE__ */ jsx162("br", {}),
|
|
13794
|
+
"Copy it now and store it securely. You will not be able to retrieve it later."
|
|
13795
|
+
] })
|
|
13796
|
+
] }),
|
|
13797
|
+
/* @__PURE__ */ jsxs96("div", { className: "flex items-center space-x-2", children: [
|
|
13798
|
+
/* @__PURE__ */ jsx162("div", { className: "flex-1", children: /* @__PURE__ */ jsx162(
|
|
13799
|
+
Input,
|
|
13800
|
+
{
|
|
13801
|
+
value: secret,
|
|
13802
|
+
readOnly: true,
|
|
13803
|
+
className: "font-mono text-sm",
|
|
13804
|
+
onClick: (e) => e.currentTarget.select()
|
|
13805
|
+
}
|
|
13806
|
+
) }),
|
|
13807
|
+
/* @__PURE__ */ jsx162(
|
|
13808
|
+
Button,
|
|
13809
|
+
{
|
|
13810
|
+
type: "button",
|
|
13811
|
+
variant: "outline",
|
|
13812
|
+
size: "icon",
|
|
13813
|
+
onClick: handleCopy,
|
|
13814
|
+
title: copied ? "Copied!" : "Copy to clipboard",
|
|
13815
|
+
children: copied ? /* @__PURE__ */ jsx162(Check, { className: "h-4 w-4 text-green-600" }) : /* @__PURE__ */ jsx162(Copy, { className: "h-4 w-4" })
|
|
13816
|
+
}
|
|
13817
|
+
)
|
|
13818
|
+
] }),
|
|
13819
|
+
copied && /* @__PURE__ */ jsx162("p", { className: "text-sm text-green-600 text-center", children: "Copied to clipboard!" }),
|
|
13820
|
+
/* @__PURE__ */ jsx162(DialogFooter, { className: "mt-4", children: /* @__PURE__ */ jsx162(Button, { onClick: handleDismiss, className: "w-full", children: "I've Saved My Secret" }) })
|
|
13821
|
+
] }) });
|
|
13822
|
+
}
|
|
13823
|
+
__name(OAuthClientSecretDisplay, "OAuthClientSecretDisplay");
|
|
13824
|
+
|
|
13825
|
+
// src/features/oauth/components/OAuthClientCard.tsx
|
|
13826
|
+
import { formatDistanceToNow } from "date-fns";
|
|
13827
|
+
import { Key, MoreVertical, Pencil, Trash2 as Trash22 } from "lucide-react";
|
|
13828
|
+
import { jsx as jsx163, jsxs as jsxs97 } from "react/jsx-runtime";
|
|
13829
|
+
function OAuthClientCard({
|
|
13830
|
+
client,
|
|
13831
|
+
onClick,
|
|
13832
|
+
onEdit,
|
|
13833
|
+
onDelete
|
|
13834
|
+
}) {
|
|
13835
|
+
const truncatedId = client.clientId.length > 12 ? `${client.clientId.slice(0, 8)}...${client.clientId.slice(-4)}` : client.clientId;
|
|
13836
|
+
const createdAgo = client.createdAt ? formatDistanceToNow(new Date(client.createdAt), { addSuffix: true }) : "Unknown";
|
|
13837
|
+
return /* @__PURE__ */ jsxs97(
|
|
13838
|
+
Card,
|
|
13839
|
+
{
|
|
13840
|
+
className: `cursor-pointer transition-colors hover:bg-accent/50 ${!client.isActive ? "opacity-60" : ""}`,
|
|
13841
|
+
onClick,
|
|
13842
|
+
children: [
|
|
13843
|
+
/* @__PURE__ */ jsxs97(CardHeader, { className: "pb-2", children: [
|
|
13844
|
+
/* @__PURE__ */ jsxs97("div", { className: "flex items-start justify-between", children: [
|
|
13845
|
+
/* @__PURE__ */ jsxs97("div", { className: "flex items-center gap-2", children: [
|
|
13846
|
+
/* @__PURE__ */ jsx163(Key, { className: "h-5 w-5 text-muted-foreground" }),
|
|
13847
|
+
/* @__PURE__ */ jsx163(CardTitle, { className: "text-lg", children: client.name })
|
|
13848
|
+
] }),
|
|
13849
|
+
/* @__PURE__ */ jsxs97("div", { className: "flex items-center gap-2", children: [
|
|
13850
|
+
/* @__PURE__ */ jsx163(Badge, { variant: client.isActive ? "default" : "secondary", children: client.isActive ? "Active" : "Inactive" }),
|
|
13851
|
+
(onEdit || onDelete) && /* @__PURE__ */ jsxs97(DropdownMenu, { children: [
|
|
13852
|
+
/* @__PURE__ */ jsx163(DropdownMenuTrigger, { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx163(Button, { render: /* @__PURE__ */ jsx163("div", {}), nativeButton: false, variant: "ghost", size: "icon", className: "h-8 w-8", children: /* @__PURE__ */ jsx163(MoreVertical, { className: "h-4 w-4" }) }) }),
|
|
13853
|
+
/* @__PURE__ */ jsxs97(DropdownMenuContent, { align: "end", children: [
|
|
13854
|
+
onEdit && /* @__PURE__ */ jsxs97(DropdownMenuItem, { onClick: (e) => {
|
|
13855
|
+
e.stopPropagation();
|
|
13856
|
+
onEdit();
|
|
13857
|
+
}, children: [
|
|
13858
|
+
/* @__PURE__ */ jsx163(Pencil, { className: "h-4 w-4 mr-2" }),
|
|
13859
|
+
"Edit"
|
|
13860
|
+
] }),
|
|
13861
|
+
onDelete && /* @__PURE__ */ jsxs97(
|
|
13862
|
+
DropdownMenuItem,
|
|
13863
|
+
{
|
|
13864
|
+
onClick: (e) => {
|
|
13865
|
+
e.stopPropagation();
|
|
13866
|
+
onDelete();
|
|
13867
|
+
},
|
|
13868
|
+
className: "text-destructive",
|
|
13869
|
+
children: [
|
|
13870
|
+
/* @__PURE__ */ jsx163(Trash22, { className: "h-4 w-4 mr-2" }),
|
|
13871
|
+
"Delete"
|
|
13872
|
+
]
|
|
13873
|
+
}
|
|
13874
|
+
)
|
|
13875
|
+
] })
|
|
13876
|
+
] })
|
|
13877
|
+
] })
|
|
13878
|
+
] }),
|
|
13879
|
+
client.description && /* @__PURE__ */ jsx163(CardDescription, { className: "line-clamp-2", children: client.description })
|
|
13880
|
+
] }),
|
|
13881
|
+
/* @__PURE__ */ jsx163(CardContent, { children: /* @__PURE__ */ jsxs97("div", { className: "flex flex-wrap gap-x-4 gap-y-1 text-sm text-muted-foreground", children: [
|
|
13882
|
+
/* @__PURE__ */ jsx163("span", { className: "font-mono", children: truncatedId }),
|
|
13883
|
+
/* @__PURE__ */ jsxs97("span", { children: [
|
|
13884
|
+
"Created ",
|
|
13885
|
+
createdAgo
|
|
13886
|
+
] }),
|
|
13887
|
+
/* @__PURE__ */ jsx163("span", { children: client.isConfidential ? "Confidential" : "Public" })
|
|
13888
|
+
] }) })
|
|
13889
|
+
]
|
|
13890
|
+
}
|
|
13891
|
+
);
|
|
13892
|
+
}
|
|
13893
|
+
__name(OAuthClientCard, "OAuthClientCard");
|
|
13894
|
+
|
|
13895
|
+
// src/features/oauth/components/OAuthClientList.tsx
|
|
13896
|
+
import { Plus as Plus2, Key as Key2 } from "lucide-react";
|
|
13897
|
+
import { jsx as jsx164, jsxs as jsxs98 } from "react/jsx-runtime";
|
|
13898
|
+
function OAuthClientList({
|
|
13899
|
+
clients,
|
|
13900
|
+
isLoading = false,
|
|
13901
|
+
error,
|
|
13902
|
+
onClientClick,
|
|
13903
|
+
onCreateClick,
|
|
13904
|
+
onEditClick,
|
|
13905
|
+
onDeleteClick,
|
|
13906
|
+
emptyStateMessage = "No OAuth applications yet. Create one to get started.",
|
|
13907
|
+
title = "OAuth Applications"
|
|
13908
|
+
}) {
|
|
13909
|
+
if (isLoading && clients.length === 0) {
|
|
13910
|
+
return /* @__PURE__ */ jsxs98("div", { className: "space-y-4", children: [
|
|
13911
|
+
/* @__PURE__ */ jsxs98("div", { className: "flex items-center justify-between", children: [
|
|
13912
|
+
/* @__PURE__ */ jsx164("h2", { className: "text-2xl font-bold", children: title }),
|
|
13913
|
+
/* @__PURE__ */ jsx164(Skeleton, { className: "h-10 w-32" })
|
|
13914
|
+
] }),
|
|
13915
|
+
/* @__PURE__ */ jsx164("div", { className: "space-y-3", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsx164(Skeleton, { className: "h-32 w-full" }, i)) })
|
|
13916
|
+
] });
|
|
13917
|
+
}
|
|
13918
|
+
if (error) {
|
|
13919
|
+
return /* @__PURE__ */ jsxs98("div", { className: "space-y-4", children: [
|
|
13920
|
+
/* @__PURE__ */ jsx164("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsx164("h2", { className: "text-2xl font-bold", children: title }) }),
|
|
13921
|
+
/* @__PURE__ */ jsx164("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-6 text-center", children: /* @__PURE__ */ jsx164("p", { className: "text-destructive", children: error.message }) })
|
|
13922
|
+
] });
|
|
13923
|
+
}
|
|
13924
|
+
if (clients.length === 0) {
|
|
13925
|
+
return /* @__PURE__ */ jsxs98("div", { className: "space-y-4", children: [
|
|
13926
|
+
/* @__PURE__ */ jsxs98("div", { className: "flex items-center justify-between", children: [
|
|
13927
|
+
/* @__PURE__ */ jsx164("h2", { className: "text-2xl font-bold", children: title }),
|
|
13928
|
+
onCreateClick && /* @__PURE__ */ jsxs98(Button, { onClick: onCreateClick, children: [
|
|
13929
|
+
/* @__PURE__ */ jsx164(Plus2, { className: "h-4 w-4 mr-2" }),
|
|
13930
|
+
"New App"
|
|
13931
|
+
] })
|
|
13932
|
+
] }),
|
|
13933
|
+
/* @__PURE__ */ jsxs98("div", { className: "rounded-lg border border-dashed p-12 text-center", children: [
|
|
13934
|
+
/* @__PURE__ */ jsx164(Key2, { className: "h-12 w-12 mx-auto text-muted-foreground mb-4" }),
|
|
13935
|
+
/* @__PURE__ */ jsx164("h3", { className: "text-lg font-medium mb-2", children: "No OAuth Applications" }),
|
|
13936
|
+
/* @__PURE__ */ jsx164("p", { className: "text-muted-foreground mb-4", children: emptyStateMessage }),
|
|
13937
|
+
onCreateClick && /* @__PURE__ */ jsxs98(Button, { onClick: onCreateClick, children: [
|
|
13938
|
+
/* @__PURE__ */ jsx164(Plus2, { className: "h-4 w-4 mr-2" }),
|
|
13939
|
+
"Create Application"
|
|
13940
|
+
] })
|
|
13941
|
+
] })
|
|
13942
|
+
] });
|
|
13943
|
+
}
|
|
13944
|
+
return /* @__PURE__ */ jsxs98("div", { className: "space-y-4", children: [
|
|
13945
|
+
/* @__PURE__ */ jsxs98("div", { className: "flex items-center justify-between", children: [
|
|
13946
|
+
/* @__PURE__ */ jsx164("h2", { className: "text-2xl font-bold", children: title }),
|
|
13947
|
+
onCreateClick && /* @__PURE__ */ jsxs98(Button, { onClick: onCreateClick, children: [
|
|
13948
|
+
/* @__PURE__ */ jsx164(Plus2, { className: "h-4 w-4 mr-2" }),
|
|
13949
|
+
"New App"
|
|
13950
|
+
] })
|
|
13951
|
+
] }),
|
|
13952
|
+
/* @__PURE__ */ jsx164("div", { className: "space-y-3", children: clients.map((client) => /* @__PURE__ */ jsx164(
|
|
13953
|
+
OAuthClientCard,
|
|
13954
|
+
{
|
|
13955
|
+
client,
|
|
13956
|
+
onClick: () => onClientClick?.(client),
|
|
13957
|
+
onEdit: onEditClick ? () => onEditClick(client) : void 0,
|
|
13958
|
+
onDelete: onDeleteClick ? () => onDeleteClick(client) : void 0
|
|
13959
|
+
},
|
|
13960
|
+
client.id || client.clientId
|
|
13961
|
+
)) })
|
|
13962
|
+
] });
|
|
13963
|
+
}
|
|
13964
|
+
__name(OAuthClientList, "OAuthClientList");
|
|
13965
|
+
|
|
13966
|
+
// src/features/oauth/components/OAuthClientForm.tsx
|
|
13967
|
+
import { useState as useState55, useCallback as useCallback25 } from "react";
|
|
13968
|
+
import { jsx as jsx165, jsxs as jsxs99 } from "react/jsx-runtime";
|
|
13969
|
+
function OAuthClientForm({
|
|
13970
|
+
client,
|
|
13971
|
+
onSubmit,
|
|
13972
|
+
onCancel,
|
|
13973
|
+
isLoading = false
|
|
13974
|
+
}) {
|
|
13975
|
+
const isEditMode = !!client;
|
|
13976
|
+
const [formState, setFormState] = useState55({
|
|
13977
|
+
name: client?.name || "",
|
|
13978
|
+
description: client?.description || "",
|
|
13979
|
+
redirectUris: client?.redirectUris?.length ? client.redirectUris : [""],
|
|
13980
|
+
allowedScopes: client?.allowedScopes || [],
|
|
13981
|
+
isConfidential: client?.isConfidential ?? true
|
|
13982
|
+
});
|
|
13983
|
+
const [errors, setErrors] = useState55({});
|
|
13984
|
+
const validate = useCallback25(() => {
|
|
13985
|
+
const newErrors = {};
|
|
13986
|
+
if (!formState.name.trim()) {
|
|
13987
|
+
newErrors.name = "Application name is required";
|
|
13988
|
+
}
|
|
13989
|
+
const validUris = formState.redirectUris.filter((uri) => uri.trim());
|
|
13990
|
+
if (validUris.length === 0) {
|
|
13991
|
+
newErrors.redirectUris = "At least one redirect URI is required";
|
|
13992
|
+
}
|
|
13993
|
+
if (formState.allowedScopes.length === 0) {
|
|
13994
|
+
newErrors.allowedScopes = "At least one scope must be selected";
|
|
13995
|
+
}
|
|
13996
|
+
setErrors(newErrors);
|
|
13997
|
+
return Object.keys(newErrors).length === 0;
|
|
13998
|
+
}, [formState]);
|
|
13999
|
+
const handleSubmit = useCallback25(
|
|
14000
|
+
async (e) => {
|
|
14001
|
+
e.preventDefault();
|
|
14002
|
+
if (!validate()) return;
|
|
14003
|
+
const data = {
|
|
14004
|
+
name: formState.name.trim(),
|
|
14005
|
+
description: formState.description.trim() || void 0,
|
|
14006
|
+
redirectUris: formState.redirectUris.filter((uri) => uri.trim()),
|
|
14007
|
+
allowedScopes: formState.allowedScopes,
|
|
14008
|
+
allowedGrantTypes: DEFAULT_GRANT_TYPES,
|
|
14009
|
+
isConfidential: formState.isConfidential
|
|
14010
|
+
};
|
|
14011
|
+
await onSubmit(data);
|
|
14012
|
+
},
|
|
14013
|
+
[formState, validate, onSubmit]
|
|
14014
|
+
);
|
|
14015
|
+
return /* @__PURE__ */ jsx165(Card, { children: /* @__PURE__ */ jsxs99("form", { onSubmit: handleSubmit, children: [
|
|
14016
|
+
/* @__PURE__ */ jsxs99(CardHeader, { children: [
|
|
14017
|
+
/* @__PURE__ */ jsx165(CardTitle, { children: isEditMode ? "Edit Application" : "Create OAuth Application" }),
|
|
14018
|
+
/* @__PURE__ */ jsx165(CardDescription, { children: isEditMode ? "Update your OAuth application settings." : "Register a new application to access the API." })
|
|
14019
|
+
] }),
|
|
14020
|
+
/* @__PURE__ */ jsxs99(CardContent, { className: "space-y-6", children: [
|
|
14021
|
+
/* @__PURE__ */ jsxs99("div", { className: "space-y-2", children: [
|
|
14022
|
+
/* @__PURE__ */ jsx165(Label, { htmlFor: "name", children: "Application Name *" }),
|
|
14023
|
+
/* @__PURE__ */ jsx165(
|
|
14024
|
+
Input,
|
|
14025
|
+
{
|
|
14026
|
+
id: "name",
|
|
14027
|
+
value: formState.name,
|
|
14028
|
+
onChange: (e) => setFormState((s) => ({ ...s, name: e.target.value })),
|
|
14029
|
+
placeholder: "My Lightroom Plugin",
|
|
14030
|
+
disabled: isLoading,
|
|
14031
|
+
className: errors.name ? "border-destructive" : ""
|
|
14032
|
+
}
|
|
14033
|
+
),
|
|
14034
|
+
errors.name && /* @__PURE__ */ jsx165("p", { className: "text-sm text-destructive", children: errors.name })
|
|
14035
|
+
] }),
|
|
14036
|
+
/* @__PURE__ */ jsxs99("div", { className: "space-y-2", children: [
|
|
14037
|
+
/* @__PURE__ */ jsx165(Label, { htmlFor: "description", children: "Description" }),
|
|
14038
|
+
/* @__PURE__ */ jsx165(
|
|
14039
|
+
Textarea,
|
|
14040
|
+
{
|
|
14041
|
+
id: "description",
|
|
14042
|
+
value: formState.description,
|
|
14043
|
+
onChange: (e) => setFormState((s) => ({ ...s, description: e.target.value })),
|
|
14044
|
+
placeholder: "A brief description of your application",
|
|
14045
|
+
disabled: isLoading,
|
|
14046
|
+
rows: 3
|
|
14047
|
+
}
|
|
14048
|
+
)
|
|
14049
|
+
] }),
|
|
14050
|
+
/* @__PURE__ */ jsx165(
|
|
14051
|
+
OAuthRedirectUriInput,
|
|
14052
|
+
{
|
|
14053
|
+
value: formState.redirectUris,
|
|
14054
|
+
onChange: (uris) => setFormState((s) => ({ ...s, redirectUris: uris })),
|
|
14055
|
+
error: errors.redirectUris,
|
|
14056
|
+
disabled: isLoading
|
|
14057
|
+
}
|
|
14058
|
+
),
|
|
14059
|
+
/* @__PURE__ */ jsx165(
|
|
14060
|
+
OAuthScopeSelector,
|
|
14061
|
+
{
|
|
14062
|
+
value: formState.allowedScopes,
|
|
14063
|
+
onChange: (scopes) => setFormState((s) => ({ ...s, allowedScopes: scopes })),
|
|
14064
|
+
error: errors.allowedScopes,
|
|
14065
|
+
disabled: isLoading
|
|
14066
|
+
}
|
|
14067
|
+
),
|
|
14068
|
+
/* @__PURE__ */ jsxs99("div", { className: "space-y-3", children: [
|
|
14069
|
+
/* @__PURE__ */ jsx165(Label, { children: "Client Type" }),
|
|
14070
|
+
/* @__PURE__ */ jsxs99(
|
|
14071
|
+
RadioGroup,
|
|
14072
|
+
{
|
|
14073
|
+
value: formState.isConfidential ? "confidential" : "public",
|
|
14074
|
+
onValueChange: (v) => setFormState((s) => ({ ...s, isConfidential: v === "confidential" })),
|
|
14075
|
+
disabled: isLoading || isEditMode,
|
|
14076
|
+
children: [
|
|
14077
|
+
/* @__PURE__ */ jsxs99("div", { className: "flex items-start space-x-3 p-3 rounded-md border", children: [
|
|
14078
|
+
/* @__PURE__ */ jsx165(RadioGroupItem, { value: "confidential", id: "confidential", className: "mt-1" }),
|
|
14079
|
+
/* @__PURE__ */ jsxs99("div", { children: [
|
|
14080
|
+
/* @__PURE__ */ jsx165(Label, { htmlFor: "confidential", className: "font-medium cursor-pointer", children: "Confidential" }),
|
|
14081
|
+
/* @__PURE__ */ jsx165("p", { className: "text-sm text-muted-foreground", children: "Server-side application that can securely store the client secret." })
|
|
14082
|
+
] })
|
|
14083
|
+
] }),
|
|
14084
|
+
/* @__PURE__ */ jsxs99("div", { className: "flex items-start space-x-3 p-3 rounded-md border", children: [
|
|
14085
|
+
/* @__PURE__ */ jsx165(RadioGroupItem, { value: "public", id: "public", className: "mt-1" }),
|
|
14086
|
+
/* @__PURE__ */ jsxs99("div", { children: [
|
|
14087
|
+
/* @__PURE__ */ jsx165(Label, { htmlFor: "public", className: "font-medium cursor-pointer", children: "Public" }),
|
|
14088
|
+
/* @__PURE__ */ jsx165("p", { className: "text-sm text-muted-foreground", children: "Mobile or desktop application. Requires PKCE for authorization." })
|
|
14089
|
+
] })
|
|
14090
|
+
] })
|
|
14091
|
+
]
|
|
14092
|
+
}
|
|
14093
|
+
),
|
|
14094
|
+
isEditMode && /* @__PURE__ */ jsx165("p", { className: "text-sm text-muted-foreground", children: "Client type cannot be changed after creation." })
|
|
14095
|
+
] })
|
|
14096
|
+
] }),
|
|
14097
|
+
/* @__PURE__ */ jsxs99(CardFooter, { className: "flex justify-end gap-3", children: [
|
|
14098
|
+
/* @__PURE__ */ jsx165(Button, { type: "button", variant: "outline", onClick: onCancel, disabled: isLoading, children: "Cancel" }),
|
|
14099
|
+
/* @__PURE__ */ jsx165(Button, { type: "submit", disabled: isLoading, children: isLoading ? "Saving..." : isEditMode ? "Save Changes" : "Create Application" })
|
|
14100
|
+
] })
|
|
14101
|
+
] }) });
|
|
14102
|
+
}
|
|
14103
|
+
__name(OAuthClientForm, "OAuthClientForm");
|
|
14104
|
+
|
|
14105
|
+
// src/features/oauth/components/OAuthClientDetail.tsx
|
|
14106
|
+
import { useState as useState56, useCallback as useCallback26 } from "react";
|
|
14107
|
+
import { format as format2 } from "date-fns";
|
|
14108
|
+
import { Copy as Copy2, Check as Check2, RefreshCw as RefreshCw2, Pencil as Pencil2, Trash2 as Trash23, ExternalLink } from "lucide-react";
|
|
14109
|
+
import { Fragment as Fragment34, jsx as jsx166, jsxs as jsxs100 } from "react/jsx-runtime";
|
|
14110
|
+
function OAuthClientDetail({
|
|
14111
|
+
client,
|
|
14112
|
+
isLoading = false,
|
|
14113
|
+
onEdit,
|
|
14114
|
+
onDelete,
|
|
14115
|
+
onRegenerateSecret
|
|
14116
|
+
}) {
|
|
14117
|
+
const [copiedField, setCopiedField] = useState56(null);
|
|
14118
|
+
const [showDeleteConfirm, setShowDeleteConfirm] = useState56(false);
|
|
14119
|
+
const [showRegenerateConfirm, setShowRegenerateConfirm] = useState56(false);
|
|
14120
|
+
const [isDeleting, setIsDeleting] = useState56(false);
|
|
14121
|
+
const [isRegenerating, setIsRegenerating] = useState56(false);
|
|
14122
|
+
const copyToClipboard = useCallback26(async (text, field) => {
|
|
14123
|
+
try {
|
|
14124
|
+
await navigator.clipboard.writeText(text);
|
|
14125
|
+
setCopiedField(field);
|
|
14126
|
+
setTimeout(() => setCopiedField(null), 2e3);
|
|
14127
|
+
} catch (err) {
|
|
14128
|
+
console.error("Failed to copy:", err);
|
|
14129
|
+
}
|
|
14130
|
+
}, []);
|
|
14131
|
+
const handleDelete = useCallback26(async () => {
|
|
14132
|
+
if (!onDelete) return;
|
|
14133
|
+
setIsDeleting(true);
|
|
14134
|
+
try {
|
|
14135
|
+
await onDelete();
|
|
14136
|
+
} finally {
|
|
14137
|
+
setIsDeleting(false);
|
|
14138
|
+
setShowDeleteConfirm(false);
|
|
14139
|
+
}
|
|
14140
|
+
}, [onDelete]);
|
|
14141
|
+
const handleRegenerateSecret = useCallback26(async () => {
|
|
14142
|
+
if (!onRegenerateSecret) return;
|
|
14143
|
+
setIsRegenerating(true);
|
|
14144
|
+
try {
|
|
14145
|
+
await onRegenerateSecret();
|
|
14146
|
+
} finally {
|
|
14147
|
+
setIsRegenerating(false);
|
|
14148
|
+
setShowRegenerateConfirm(false);
|
|
14149
|
+
}
|
|
14150
|
+
}, [onRegenerateSecret]);
|
|
14151
|
+
const createdDate = client.createdAt ? format2(new Date(client.createdAt), "MMMM d, yyyy") : "Unknown";
|
|
14152
|
+
return /* @__PURE__ */ jsxs100(Fragment34, { children: [
|
|
14153
|
+
/* @__PURE__ */ jsxs100(Card, { children: [
|
|
14154
|
+
/* @__PURE__ */ jsx166(CardHeader, { children: /* @__PURE__ */ jsxs100("div", { className: "flex items-start justify-between", children: [
|
|
14155
|
+
/* @__PURE__ */ jsxs100("div", { children: [
|
|
14156
|
+
/* @__PURE__ */ jsx166(CardTitle, { className: "text-2xl", children: client.name }),
|
|
14157
|
+
client.description && /* @__PURE__ */ jsx166(CardDescription, { className: "mt-1", children: client.description })
|
|
14158
|
+
] }),
|
|
14159
|
+
/* @__PURE__ */ jsxs100("div", { className: "flex items-center gap-2", children: [
|
|
14160
|
+
/* @__PURE__ */ jsx166(Badge, { variant: client.isActive ? "default" : "secondary", children: client.isActive ? "Active" : "Inactive" }),
|
|
14161
|
+
/* @__PURE__ */ jsx166(Badge, { variant: "outline", children: client.isConfidential ? "Confidential" : "Public" })
|
|
14162
|
+
] })
|
|
14163
|
+
] }) }),
|
|
14164
|
+
/* @__PURE__ */ jsxs100(CardContent, { className: "space-y-6", children: [
|
|
14165
|
+
/* @__PURE__ */ jsxs100("div", { className: "space-y-2", children: [
|
|
14166
|
+
/* @__PURE__ */ jsx166(Label, { children: "Client ID" }),
|
|
14167
|
+
/* @__PURE__ */ jsxs100("div", { className: "flex gap-2", children: [
|
|
14168
|
+
/* @__PURE__ */ jsx166(Input, { value: client.clientId, readOnly: true, className: "font-mono" }),
|
|
14169
|
+
/* @__PURE__ */ jsx166(
|
|
14170
|
+
Button,
|
|
14171
|
+
{
|
|
14172
|
+
variant: "outline",
|
|
14173
|
+
size: "icon",
|
|
14174
|
+
onClick: () => copyToClipboard(client.clientId, "clientId"),
|
|
14175
|
+
title: "Copy Client ID",
|
|
14176
|
+
children: copiedField === "clientId" ? /* @__PURE__ */ jsx166(Check2, { className: "h-4 w-4 text-green-600" }) : /* @__PURE__ */ jsx166(Copy2, { className: "h-4 w-4" })
|
|
14177
|
+
}
|
|
14178
|
+
)
|
|
14179
|
+
] })
|
|
14180
|
+
] }),
|
|
14181
|
+
/* @__PURE__ */ jsxs100("div", { className: "space-y-2", children: [
|
|
14182
|
+
/* @__PURE__ */ jsx166(Label, { children: "Client Secret" }),
|
|
14183
|
+
/* @__PURE__ */ jsxs100("div", { className: "flex gap-2", children: [
|
|
14184
|
+
/* @__PURE__ */ jsx166(Input, { value: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", readOnly: true, className: "font-mono" }),
|
|
14185
|
+
onRegenerateSecret && /* @__PURE__ */ jsx166(
|
|
14186
|
+
Button,
|
|
14187
|
+
{
|
|
14188
|
+
variant: "outline",
|
|
14189
|
+
size: "icon",
|
|
14190
|
+
onClick: () => setShowRegenerateConfirm(true),
|
|
14191
|
+
title: "Regenerate Secret",
|
|
14192
|
+
disabled: isLoading,
|
|
14193
|
+
children: /* @__PURE__ */ jsx166(RefreshCw2, { className: "h-4 w-4" })
|
|
14194
|
+
}
|
|
14195
|
+
)
|
|
14196
|
+
] }),
|
|
14197
|
+
/* @__PURE__ */ jsx166("p", { className: "text-xs text-muted-foreground", children: "Regenerating will invalidate the current secret and all existing tokens." })
|
|
14198
|
+
] }),
|
|
14199
|
+
/* @__PURE__ */ jsx166(Separator, {}),
|
|
14200
|
+
/* @__PURE__ */ jsxs100("div", { className: "space-y-2", children: [
|
|
14201
|
+
/* @__PURE__ */ jsx166(Label, { children: "Redirect URIs" }),
|
|
14202
|
+
/* @__PURE__ */ jsx166("ul", { className: "space-y-1", children: client.redirectUris.map((uri, index) => /* @__PURE__ */ jsxs100("li", { className: "flex items-center gap-2 text-sm font-mono", children: [
|
|
14203
|
+
/* @__PURE__ */ jsx166(ExternalLink, { className: "h-3 w-3 text-muted-foreground" }),
|
|
14204
|
+
uri
|
|
14205
|
+
] }, index)) })
|
|
14206
|
+
] }),
|
|
14207
|
+
/* @__PURE__ */ jsxs100("div", { className: "space-y-2", children: [
|
|
14208
|
+
/* @__PURE__ */ jsx166(Label, { children: "Allowed Scopes" }),
|
|
14209
|
+
/* @__PURE__ */ jsx166("div", { className: "flex flex-wrap gap-2", children: client.allowedScopes.map((scope) => /* @__PURE__ */ jsx166(Badge, { variant: "secondary", children: OAUTH_SCOPE_DISPLAY[scope]?.name || scope }, scope)) })
|
|
14210
|
+
] }),
|
|
14211
|
+
/* @__PURE__ */ jsxs100("div", { className: "space-y-2", children: [
|
|
14212
|
+
/* @__PURE__ */ jsx166(Label, { children: "Grant Types" }),
|
|
14213
|
+
/* @__PURE__ */ jsx166("div", { className: "flex flex-wrap gap-2", children: client.allowedGrantTypes.map((grant) => /* @__PURE__ */ jsx166(Badge, { variant: "outline", children: grant.replace(/_/g, " ") }, grant)) })
|
|
14214
|
+
] }),
|
|
14215
|
+
/* @__PURE__ */ jsx166(Separator, {}),
|
|
14216
|
+
/* @__PURE__ */ jsx166("div", { className: "flex flex-wrap gap-x-6 gap-y-2 text-sm text-muted-foreground", children: /* @__PURE__ */ jsxs100("span", { children: [
|
|
14217
|
+
"Created: ",
|
|
14218
|
+
createdDate
|
|
14219
|
+
] }) }),
|
|
14220
|
+
/* @__PURE__ */ jsxs100("div", { className: "flex gap-3 pt-4", children: [
|
|
14221
|
+
onEdit && /* @__PURE__ */ jsxs100(Button, { variant: "outline", onClick: onEdit, disabled: isLoading, children: [
|
|
14222
|
+
/* @__PURE__ */ jsx166(Pencil2, { className: "h-4 w-4 mr-2" }),
|
|
14223
|
+
"Edit"
|
|
14224
|
+
] }),
|
|
14225
|
+
onDelete && /* @__PURE__ */ jsxs100(
|
|
14226
|
+
Button,
|
|
14227
|
+
{
|
|
14228
|
+
variant: "destructive",
|
|
14229
|
+
onClick: () => setShowDeleteConfirm(true),
|
|
14230
|
+
disabled: isLoading,
|
|
14231
|
+
children: [
|
|
14232
|
+
/* @__PURE__ */ jsx166(Trash23, { className: "h-4 w-4 mr-2" }),
|
|
14233
|
+
"Delete"
|
|
14234
|
+
]
|
|
14235
|
+
}
|
|
14236
|
+
)
|
|
14237
|
+
] })
|
|
14238
|
+
] })
|
|
14239
|
+
] }),
|
|
14240
|
+
/* @__PURE__ */ jsx166(AlertDialog, { open: showDeleteConfirm, onOpenChange: setShowDeleteConfirm, children: /* @__PURE__ */ jsxs100(AlertDialogContent, { children: [
|
|
14241
|
+
/* @__PURE__ */ jsxs100(AlertDialogHeader, { children: [
|
|
14242
|
+
/* @__PURE__ */ jsx166(AlertDialogTitle, { children: "Delete OAuth Application?" }),
|
|
14243
|
+
/* @__PURE__ */ jsxs100(AlertDialogDescription, { children: [
|
|
14244
|
+
'This will permanently delete "',
|
|
14245
|
+
client.name,
|
|
14246
|
+
'" and revoke all access tokens. This action cannot be undone.'
|
|
14247
|
+
] })
|
|
14248
|
+
] }),
|
|
14249
|
+
/* @__PURE__ */ jsxs100(AlertDialogFooter, { children: [
|
|
14250
|
+
/* @__PURE__ */ jsx166(AlertDialogCancel, { disabled: isDeleting, children: "Cancel" }),
|
|
14251
|
+
/* @__PURE__ */ jsx166(
|
|
14252
|
+
AlertDialogAction,
|
|
14253
|
+
{
|
|
14254
|
+
onClick: handleDelete,
|
|
14255
|
+
disabled: isDeleting,
|
|
14256
|
+
className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
14257
|
+
children: isDeleting ? "Deleting..." : "Delete"
|
|
14258
|
+
}
|
|
14259
|
+
)
|
|
14260
|
+
] })
|
|
14261
|
+
] }) }),
|
|
14262
|
+
/* @__PURE__ */ jsx166(AlertDialog, { open: showRegenerateConfirm, onOpenChange: setShowRegenerateConfirm, children: /* @__PURE__ */ jsxs100(AlertDialogContent, { children: [
|
|
14263
|
+
/* @__PURE__ */ jsxs100(AlertDialogHeader, { children: [
|
|
14264
|
+
/* @__PURE__ */ jsx166(AlertDialogTitle, { children: "Regenerate Client Secret?" }),
|
|
14265
|
+
/* @__PURE__ */ jsx166(AlertDialogDescription, { children: "This will generate a new client secret and invalidate the old one. All existing tokens will be revoked. You will need to update your application with the new secret." })
|
|
14266
|
+
] }),
|
|
14267
|
+
/* @__PURE__ */ jsxs100(AlertDialogFooter, { children: [
|
|
14268
|
+
/* @__PURE__ */ jsx166(AlertDialogCancel, { disabled: isRegenerating, children: "Cancel" }),
|
|
14269
|
+
/* @__PURE__ */ jsx166(AlertDialogAction, { onClick: handleRegenerateSecret, disabled: isRegenerating, children: isRegenerating ? "Regenerating..." : "Regenerate" })
|
|
14270
|
+
] })
|
|
14271
|
+
] }) })
|
|
14272
|
+
] });
|
|
14273
|
+
}
|
|
14274
|
+
__name(OAuthClientDetail, "OAuthClientDetail");
|
|
14275
|
+
|
|
14276
|
+
// src/features/oauth/components/consent/OAuthConsentHeader.tsx
|
|
14277
|
+
import { Shield } from "lucide-react";
|
|
14278
|
+
import { jsx as jsx167, jsxs as jsxs101 } from "react/jsx-runtime";
|
|
14279
|
+
function OAuthConsentHeader({
|
|
14280
|
+
client,
|
|
14281
|
+
logoUrl,
|
|
14282
|
+
appName = "Only35"
|
|
14283
|
+
}) {
|
|
14284
|
+
return /* @__PURE__ */ jsxs101("div", { className: "text-center space-y-4", children: [
|
|
14285
|
+
/* @__PURE__ */ jsx167("div", { className: "flex justify-center", children: logoUrl ? /* @__PURE__ */ jsx167(
|
|
14286
|
+
"img",
|
|
14287
|
+
{
|
|
14288
|
+
src: logoUrl,
|
|
14289
|
+
alt: appName,
|
|
14290
|
+
className: "h-12 w-auto"
|
|
14291
|
+
}
|
|
14292
|
+
) : /* @__PURE__ */ jsx167("div", { className: "h-12 w-12 rounded-full bg-primary flex items-center justify-center", children: /* @__PURE__ */ jsx167(Shield, { className: "h-6 w-6 text-primary-foreground" }) }) }),
|
|
14293
|
+
/* @__PURE__ */ jsxs101("div", { className: "space-y-2", children: [
|
|
14294
|
+
/* @__PURE__ */ jsxs101("h1", { className: "text-2xl font-bold", children: [
|
|
14295
|
+
"Authorize ",
|
|
14296
|
+
client.name
|
|
14297
|
+
] }),
|
|
14298
|
+
/* @__PURE__ */ jsxs101("p", { className: "text-muted-foreground", children: [
|
|
14299
|
+
/* @__PURE__ */ jsx167("span", { className: "font-medium text-foreground", children: client.name }),
|
|
14300
|
+
" ",
|
|
14301
|
+
"wants to access your ",
|
|
14302
|
+
appName,
|
|
14303
|
+
" account"
|
|
14304
|
+
] })
|
|
14305
|
+
] })
|
|
14306
|
+
] });
|
|
14307
|
+
}
|
|
14308
|
+
__name(OAuthConsentHeader, "OAuthConsentHeader");
|
|
14309
|
+
|
|
14310
|
+
// src/features/oauth/components/consent/OAuthScopeList.tsx
|
|
14311
|
+
import {
|
|
14312
|
+
Eye,
|
|
14313
|
+
Pencil as Pencil3,
|
|
14314
|
+
Image as Image16,
|
|
14315
|
+
Upload,
|
|
14316
|
+
Film,
|
|
14317
|
+
FolderPlus,
|
|
14318
|
+
User,
|
|
14319
|
+
Shield as Shield2
|
|
14320
|
+
} from "lucide-react";
|
|
14321
|
+
import { jsx as jsx168, jsxs as jsxs102 } from "react/jsx-runtime";
|
|
14322
|
+
var SCOPE_ICONS = {
|
|
14323
|
+
eye: Eye,
|
|
14324
|
+
pencil: Pencil3,
|
|
14325
|
+
image: Image16,
|
|
14326
|
+
upload: Upload,
|
|
14327
|
+
film: Film,
|
|
14328
|
+
"folder-plus": FolderPlus,
|
|
14329
|
+
user: User,
|
|
14330
|
+
shield: Shield2
|
|
14331
|
+
};
|
|
14332
|
+
function OAuthScopeList({ scopes }) {
|
|
14333
|
+
if (scopes.length === 0) {
|
|
14334
|
+
return null;
|
|
14335
|
+
}
|
|
14336
|
+
return /* @__PURE__ */ jsxs102("div", { className: "space-y-3", children: [
|
|
14337
|
+
/* @__PURE__ */ jsx168("h2", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wide", children: "This will allow the application to:" }),
|
|
14338
|
+
/* @__PURE__ */ jsx168("ul", { className: "space-y-3", children: scopes.map((scope) => {
|
|
14339
|
+
const IconComponent = scope.icon ? SCOPE_ICONS[scope.icon] : Eye;
|
|
14340
|
+
return /* @__PURE__ */ jsxs102(
|
|
14341
|
+
"li",
|
|
14342
|
+
{
|
|
14343
|
+
className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50",
|
|
14344
|
+
children: [
|
|
14345
|
+
/* @__PURE__ */ jsx168("div", { className: "flex-shrink-0 mt-0.5", children: /* @__PURE__ */ jsx168("div", { className: "h-8 w-8 rounded-full bg-primary/10 flex items-center justify-center", children: IconComponent && /* @__PURE__ */ jsx168(IconComponent, { className: "h-4 w-4 text-primary" }) }) }),
|
|
14346
|
+
/* @__PURE__ */ jsxs102("div", { className: "flex-1", children: [
|
|
14347
|
+
/* @__PURE__ */ jsx168("p", { className: "font-medium", children: scope.name }),
|
|
14348
|
+
/* @__PURE__ */ jsx168("p", { className: "text-sm text-muted-foreground", children: scope.description })
|
|
14349
|
+
] })
|
|
14350
|
+
]
|
|
14351
|
+
},
|
|
14352
|
+
scope.scope
|
|
14353
|
+
);
|
|
14354
|
+
}) })
|
|
14355
|
+
] });
|
|
14356
|
+
}
|
|
14357
|
+
__name(OAuthScopeList, "OAuthScopeList");
|
|
14358
|
+
|
|
14359
|
+
// src/features/oauth/components/consent/OAuthConsentActions.tsx
|
|
14360
|
+
import { jsx as jsx169, jsxs as jsxs103 } from "react/jsx-runtime";
|
|
14361
|
+
function OAuthConsentActions({
|
|
14362
|
+
onApprove,
|
|
14363
|
+
onDeny,
|
|
14364
|
+
isLoading = false
|
|
14365
|
+
}) {
|
|
14366
|
+
return /* @__PURE__ */ jsxs103("div", { className: "flex flex-col sm:flex-row gap-3", children: [
|
|
14367
|
+
/* @__PURE__ */ jsx169(
|
|
14368
|
+
Button,
|
|
14369
|
+
{
|
|
14370
|
+
variant: "outline",
|
|
14371
|
+
onClick: onDeny,
|
|
14372
|
+
disabled: isLoading,
|
|
14373
|
+
className: "flex-1",
|
|
14374
|
+
children: "Deny"
|
|
14375
|
+
}
|
|
14376
|
+
),
|
|
14377
|
+
/* @__PURE__ */ jsx169(
|
|
14378
|
+
Button,
|
|
14379
|
+
{
|
|
14380
|
+
onClick: onApprove,
|
|
14381
|
+
disabled: isLoading,
|
|
14382
|
+
className: "flex-1",
|
|
14383
|
+
children: isLoading ? "Authorizing..." : "Authorize"
|
|
14384
|
+
}
|
|
14385
|
+
)
|
|
14386
|
+
] });
|
|
14387
|
+
}
|
|
14388
|
+
__name(OAuthConsentActions, "OAuthConsentActions");
|
|
14389
|
+
|
|
14390
|
+
// src/features/oauth/components/consent/OAuthConsentScreen.tsx
|
|
14391
|
+
import { ExternalLink as ExternalLink2, AlertTriangle as AlertTriangle2, Loader2 as Loader22 } from "lucide-react";
|
|
14392
|
+
import { jsx as jsx170, jsxs as jsxs104 } from "react/jsx-runtime";
|
|
14393
|
+
function OAuthConsentScreen({
|
|
14394
|
+
params,
|
|
14395
|
+
logoUrl,
|
|
14396
|
+
appName = "Only35",
|
|
14397
|
+
termsUrl = "/terms",
|
|
14398
|
+
privacyUrl = "/privacy"
|
|
14399
|
+
}) {
|
|
14400
|
+
const { clientInfo, isLoading, error, approve, deny, isSubmitting } = useOAuthConsent(params);
|
|
14401
|
+
if (isLoading) {
|
|
14402
|
+
return /* @__PURE__ */ jsx170("div", { className: "min-h-screen flex items-center justify-center p-4", children: /* @__PURE__ */ jsx170(Card, { className: "w-full max-w-md", children: /* @__PURE__ */ jsxs104(CardContent, { className: "flex flex-col items-center justify-center py-12", children: [
|
|
14403
|
+
/* @__PURE__ */ jsx170(Loader22, { className: "h-8 w-8 animate-spin text-muted-foreground" }),
|
|
14404
|
+
/* @__PURE__ */ jsx170("p", { className: "mt-4 text-muted-foreground", children: "Loading authorization request..." })
|
|
14405
|
+
] }) }) });
|
|
14406
|
+
}
|
|
14407
|
+
if (error || !clientInfo) {
|
|
14408
|
+
return /* @__PURE__ */ jsx170("div", { className: "min-h-screen flex items-center justify-center p-4", children: /* @__PURE__ */ jsx170(Card, { className: "w-full max-w-md", children: /* @__PURE__ */ jsx170(CardContent, { className: "py-8", children: /* @__PURE__ */ jsxs104(Alert, { variant: "destructive", children: [
|
|
14409
|
+
/* @__PURE__ */ jsx170(AlertTriangle2, { className: "h-4 w-4" }),
|
|
14410
|
+
/* @__PURE__ */ jsx170(AlertDescription, { children: error?.message || "Invalid authorization request. Please try again." })
|
|
14411
|
+
] }) }) }) });
|
|
14412
|
+
}
|
|
14413
|
+
const { client, scopes } = clientInfo;
|
|
14414
|
+
return /* @__PURE__ */ jsx170("div", { className: "min-h-screen flex items-center justify-center p-4 bg-muted/30", children: /* @__PURE__ */ jsxs104(Card, { className: "w-full max-w-md", children: [
|
|
14415
|
+
/* @__PURE__ */ jsxs104(CardContent, { className: "pt-6 space-y-6", children: [
|
|
14416
|
+
/* @__PURE__ */ jsx170(
|
|
14417
|
+
OAuthConsentHeader,
|
|
14418
|
+
{
|
|
14419
|
+
client,
|
|
14420
|
+
logoUrl,
|
|
14421
|
+
appName
|
|
14422
|
+
}
|
|
14423
|
+
),
|
|
14424
|
+
/* @__PURE__ */ jsx170(Separator, {}),
|
|
14425
|
+
/* @__PURE__ */ jsx170(OAuthScopeList, { scopes }),
|
|
14426
|
+
/* @__PURE__ */ jsx170(Separator, {}),
|
|
14427
|
+
/* @__PURE__ */ jsxs104("div", { className: "flex items-start gap-2 text-sm text-muted-foreground", children: [
|
|
14428
|
+
/* @__PURE__ */ jsx170(ExternalLink2, { className: "h-4 w-4 mt-0.5 flex-shrink-0" }),
|
|
14429
|
+
/* @__PURE__ */ jsxs104("div", { children: [
|
|
14430
|
+
/* @__PURE__ */ jsx170("span", { children: "Authorizing will redirect you to:" }),
|
|
14431
|
+
/* @__PURE__ */ jsx170("p", { className: "font-mono text-xs mt-1 break-all", children: params.redirectUri })
|
|
14432
|
+
] })
|
|
14433
|
+
] }),
|
|
14434
|
+
/* @__PURE__ */ jsx170(
|
|
14435
|
+
OAuthConsentActions,
|
|
14436
|
+
{
|
|
14437
|
+
onApprove: approve,
|
|
14438
|
+
onDeny: deny,
|
|
14439
|
+
isLoading: isSubmitting
|
|
14440
|
+
}
|
|
14441
|
+
)
|
|
14442
|
+
] }),
|
|
14443
|
+
/* @__PURE__ */ jsx170(CardFooter, { className: "justify-center", children: /* @__PURE__ */ jsxs104("p", { className: "text-xs text-center text-muted-foreground", children: [
|
|
14444
|
+
"By authorizing, you agree to the app's",
|
|
14445
|
+
" ",
|
|
14446
|
+
/* @__PURE__ */ jsx170("a", { href: termsUrl, className: "underline hover:text-foreground", target: "_blank", rel: "noopener", children: "Terms of Service" }),
|
|
14447
|
+
" ",
|
|
14448
|
+
"and",
|
|
14449
|
+
" ",
|
|
14450
|
+
/* @__PURE__ */ jsx170("a", { href: privacyUrl, className: "underline hover:text-foreground", target: "_blank", rel: "noopener", children: "Privacy Policy" }),
|
|
14451
|
+
"."
|
|
14452
|
+
] }) })
|
|
14453
|
+
] }) });
|
|
14454
|
+
}
|
|
14455
|
+
__name(OAuthConsentScreen, "OAuthConsentScreen");
|
|
14456
|
+
|
|
13278
14457
|
export {
|
|
13279
14458
|
JsonApiProvider,
|
|
13280
14459
|
useJsonApiGet,
|
|
@@ -13650,6 +14829,18 @@ export {
|
|
|
13650
14829
|
useRoleTableStructure,
|
|
13651
14830
|
RolesList,
|
|
13652
14831
|
UserRolesList,
|
|
14832
|
+
OAuthRedirectUriInput,
|
|
14833
|
+
OAuthScopeSelector,
|
|
14834
|
+
OAuthClientSecretDisplay,
|
|
14835
|
+
OAuthClientCard,
|
|
14836
|
+
OAuthClientList,
|
|
14837
|
+
OAuthClientForm,
|
|
14838
|
+
OAuthClientDetail,
|
|
14839
|
+
OAuthConsentHeader,
|
|
14840
|
+
OAuthScopeList,
|
|
14841
|
+
OAuthConsentActions,
|
|
14842
|
+
useOAuthConsent,
|
|
14843
|
+
OAuthConsentScreen,
|
|
13653
14844
|
AddUserToRole,
|
|
13654
14845
|
UserAvatarEditor,
|
|
13655
14846
|
UserDeleter,
|
|
@@ -13672,6 +14863,8 @@ export {
|
|
|
13672
14863
|
useSocket,
|
|
13673
14864
|
useUserSearch,
|
|
13674
14865
|
useUserTableStructure,
|
|
13675
|
-
useContentTableStructure
|
|
14866
|
+
useContentTableStructure,
|
|
14867
|
+
useOAuthClients,
|
|
14868
|
+
useOAuthClient
|
|
13676
14869
|
};
|
|
13677
|
-
//# sourceMappingURL=chunk-
|
|
14870
|
+
//# sourceMappingURL=chunk-6BDOZDZ3.mjs.map
|