@sentroy-co/client-sdk 2.13.6 → 2.13.8

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.
Files changed (40) hide show
  1. package/dist/auth/admin/index.d.ts +52 -0
  2. package/dist/auth/admin/index.d.ts.map +1 -0
  3. package/dist/auth/admin/index.js +123 -0
  4. package/dist/auth/admin/index.js.map +1 -0
  5. package/dist/auth/client.d.ts +86 -0
  6. package/dist/auth/client.d.ts.map +1 -0
  7. package/dist/auth/client.js +265 -0
  8. package/dist/auth/client.js.map +1 -0
  9. package/dist/auth/http.d.ts +19 -0
  10. package/dist/auth/http.d.ts.map +1 -0
  11. package/dist/auth/http.js +74 -0
  12. package/dist/auth/http.js.map +1 -0
  13. package/dist/auth/index.d.ts +16 -0
  14. package/dist/auth/index.d.ts.map +1 -0
  15. package/dist/auth/index.js +20 -0
  16. package/dist/auth/index.js.map +1 -0
  17. package/dist/auth/react/index.d.ts +41 -0
  18. package/dist/auth/react/index.d.ts.map +1 -0
  19. package/dist/auth/react/index.js +52 -0
  20. package/dist/auth/react/index.js.map +1 -0
  21. package/dist/auth/types.d.ts +50 -0
  22. package/dist/auth/types.d.ts.map +1 -0
  23. package/dist/auth/types.js +21 -0
  24. package/dist/auth/types.js.map +1 -0
  25. package/dist/react/MediaManager.d.ts.map +1 -1
  26. package/dist/react/MediaManager.js +10 -2
  27. package/dist/react/MediaManager.js.map +1 -1
  28. package/dist/react/lib/Lightbox.d.ts +14 -5
  29. package/dist/react/lib/Lightbox.d.ts.map +1 -1
  30. package/dist/react/lib/Lightbox.js +203 -26
  31. package/dist/react/lib/Lightbox.js.map +1 -1
  32. package/package.json +16 -1
  33. package/src/auth/admin/index.ts +191 -0
  34. package/src/auth/client.ts +344 -0
  35. package/src/auth/http.ts +101 -0
  36. package/src/auth/index.ts +26 -0
  37. package/src/auth/react/index.tsx +100 -0
  38. package/src/auth/types.ts +60 -0
  39. package/src/react/MediaManager.tsx +36 -12
  40. package/src/react/lib/Lightbox.tsx +369 -78
@@ -5,42 +5,219 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const thumbnails_1 = require("../../thumbnails");
7
7
  const utils_1 = require("./utils");
8
+ const MIN_SCALE = 0.05;
9
+ const MAX_SCALE = 8;
8
10
  function Lightbox({ media, onClose, onPrev, onNext, className, }) {
11
+ const kind = (0, utils_1.detectKind)(media);
12
+ const url = kind === "image"
13
+ ? (0, thumbnails_1.pickPresetThumbnailUrl)(media, "preview") ?? media.url ?? media.downloadUrl
14
+ : media.url ?? media.downloadUrl;
15
+ // Body scroll lock + key handlers — bu effect media değişse de aynı kalır.
16
+ const onCloseRef = (0, react_1.useRef)(onClose);
17
+ const onPrevRef = (0, react_1.useRef)(onPrev);
18
+ const onNextRef = (0, react_1.useRef)(onNext);
19
+ onCloseRef.current = onClose;
20
+ onPrevRef.current = onPrev;
21
+ onNextRef.current = onNext;
9
22
  (0, react_1.useEffect)(() => {
10
- const onKey = (e) => {
11
- if (e.key === "Escape")
12
- onClose();
13
- if (e.key === "ArrowLeft" && onPrev)
14
- onPrev();
15
- if (e.key === "ArrowRight" && onNext)
16
- onNext();
17
- };
18
- document.addEventListener("keydown", onKey);
19
23
  document.body.style.overflow = "hidden";
20
24
  return () => {
21
- document.removeEventListener("keydown", onKey);
22
25
  document.body.style.overflow = "";
23
26
  };
24
- }, [onClose, onPrev, onNext]);
25
- const kind = (0, utils_1.detectKind)(media);
26
- // Lightbox modal büyük preview ama 4K/orijinal gerekmez. Image
27
- // için "preview" preset (~960px) kullan, video/audio/diğerlerinde
28
- // orijinal URL'i akıt.
29
- const url = kind === "image"
30
- ? (0, thumbnails_1.pickPresetThumbnailUrl)(media, "preview") ?? media.url ?? media.downloadUrl
31
- : media.url ?? media.downloadUrl;
27
+ }, []);
28
+ // ── Image-only zoom/pan state ──────────────────────────────────────────
29
+ const stageRef = (0, react_1.useRef)(null);
30
+ const imgRef = (0, react_1.useRef)(null);
31
+ const [natural, setNatural] = (0, react_1.useState)(null);
32
+ const [fitScale, setFitScale] = (0, react_1.useState)(1);
33
+ const [scale, setScale] = (0, react_1.useState)(1);
34
+ const [translate, setTranslate] = (0, react_1.useState)({ x: 0, y: 0 });
35
+ const dragStateRef = (0, react_1.useRef)(null);
36
+ const [isDragging, setIsDragging] = (0, react_1.useState)(false);
37
+ // Yeni media → state sıfırla (fit recompute imgLoad'da gelir)
38
+ (0, react_1.useEffect)(() => {
39
+ setNatural(null);
40
+ setFitScale(1);
41
+ setScale(1);
42
+ setTranslate({ x: 0, y: 0 });
43
+ }, [media.id]);
44
+ const recomputeFit = (0, react_1.useCallback)(() => {
45
+ const stage = stageRef.current;
46
+ if (!stage || !natural)
47
+ return;
48
+ // Stage'in viewport içindeki boyutu — padding/border yok varsayıyoruz.
49
+ const sw = stage.clientWidth;
50
+ const sh = stage.clientHeight;
51
+ if (sw <= 0 || sh <= 0)
52
+ return;
53
+ const fit = Math.min(sw / natural.w, sh / natural.h, 1);
54
+ setFitScale(fit);
55
+ setScale(fit);
56
+ setTranslate({ x: 0, y: 0 });
57
+ }, [natural]);
58
+ (0, react_1.useLayoutEffect)(() => {
59
+ recomputeFit();
60
+ }, [recomputeFit]);
61
+ (0, react_1.useEffect)(() => {
62
+ const onResize = () => recomputeFit();
63
+ window.addEventListener("resize", onResize);
64
+ return () => window.removeEventListener("resize", onResize);
65
+ }, [recomputeFit]);
66
+ const handleImgLoad = (0, react_1.useCallback)((e) => {
67
+ const img = e.currentTarget;
68
+ setNatural({ w: img.naturalWidth, h: img.naturalHeight });
69
+ }, []);
70
+ // Zoom around a pivot (cursor or center). Pivot stage-relative coords.
71
+ const zoomAt = (0, react_1.useCallback)((nextScale, pivot) => {
72
+ const stage = stageRef.current;
73
+ if (!stage)
74
+ return;
75
+ const clamped = Math.max(MIN_SCALE, Math.min(MAX_SCALE, nextScale));
76
+ const rect = stage.getBoundingClientRect();
77
+ const cx = pivot?.x ?? rect.width / 2;
78
+ const cy = pivot?.y ?? rect.height / 2;
79
+ // Image origin relative to stage center (current translate accounted)
80
+ // p = ((c - center) - t) / s → world coords. Yeni translate:
81
+ // t' = (c - center) - p * s'
82
+ const ox = cx - rect.width / 2 - translate.x;
83
+ const oy = cy - rect.height / 2 - translate.y;
84
+ const ratio = clamped / scale;
85
+ const tx = cx - rect.width / 2 - ox * ratio;
86
+ const ty = cy - rect.height / 2 - oy * ratio;
87
+ setScale(clamped);
88
+ setTranslate({ x: tx, y: ty });
89
+ }, [scale, translate]);
90
+ const zoomBy = (0, react_1.useCallback)((factor, pivot) => zoomAt(scale * factor, pivot), [scale, zoomAt]);
91
+ const resetView = (0, react_1.useCallback)(() => {
92
+ setScale(fitScale);
93
+ setTranslate({ x: 0, y: 0 });
94
+ }, [fitScale]);
95
+ const toggle1x = (0, react_1.useCallback)(() => {
96
+ if (Math.abs(scale - 1) < 0.001) {
97
+ resetView();
98
+ }
99
+ else {
100
+ setScale(1);
101
+ setTranslate({ x: 0, y: 0 });
102
+ }
103
+ }, [scale, resetView]);
104
+ // Wheel zoom (cursor-aware)
105
+ const handleWheel = (0, react_1.useCallback)((e) => {
106
+ if (kind !== "image")
107
+ return;
108
+ e.preventDefault();
109
+ const stage = stageRef.current;
110
+ if (!stage)
111
+ return;
112
+ const rect = stage.getBoundingClientRect();
113
+ const pivot = { x: e.clientX - rect.left, y: e.clientY - rect.top };
114
+ const factor = e.deltaY < 0 ? 1.12 : 1 / 1.12;
115
+ zoomBy(factor, pivot);
116
+ }, [kind, zoomBy]);
117
+ // Drag-to-pan
118
+ const onPointerDown = (0, react_1.useCallback)((e) => {
119
+ if (kind !== "image")
120
+ return;
121
+ // Sadece sol tıklama (button 0) veya touch
122
+ if (e.button !== 0 && e.pointerType === "mouse")
123
+ return;
124
+ dragStateRef.current = {
125
+ active: true,
126
+ startX: e.clientX,
127
+ startY: e.clientY,
128
+ baseX: translate.x,
129
+ baseY: translate.y,
130
+ };
131
+ setIsDragging(true);
132
+ e.target.setPointerCapture?.(e.pointerId);
133
+ }, [kind, translate]);
134
+ const onPointerMove = (0, react_1.useCallback)((e) => {
135
+ const ds = dragStateRef.current;
136
+ if (!ds?.active)
137
+ return;
138
+ e.preventDefault();
139
+ const dx = e.clientX - ds.startX;
140
+ const dy = e.clientY - ds.startY;
141
+ setTranslate({ x: ds.baseX + dx, y: ds.baseY + dy });
142
+ }, []);
143
+ const endDrag = (0, react_1.useCallback)(() => {
144
+ if (dragStateRef.current?.active) {
145
+ dragStateRef.current.active = false;
146
+ setIsDragging(false);
147
+ }
148
+ }, []);
149
+ // Klavye
150
+ (0, react_1.useEffect)(() => {
151
+ const onKey = (e) => {
152
+ if (e.target instanceof HTMLElement &&
153
+ (e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA")) {
154
+ return;
155
+ }
156
+ if (e.key === "Escape") {
157
+ e.preventDefault();
158
+ onCloseRef.current();
159
+ }
160
+ else if (e.key === "ArrowLeft" && onPrevRef.current) {
161
+ e.preventDefault();
162
+ onPrevRef.current();
163
+ }
164
+ else if (e.key === "ArrowRight" && onNextRef.current) {
165
+ e.preventDefault();
166
+ onNextRef.current();
167
+ }
168
+ else if (e.key === "+" || e.key === "=") {
169
+ e.preventDefault();
170
+ zoomBy(1.2);
171
+ }
172
+ else if (e.key === "-" || e.key === "_") {
173
+ e.preventDefault();
174
+ zoomBy(1 / 1.2);
175
+ }
176
+ else if (e.key === "0") {
177
+ e.preventDefault();
178
+ resetView();
179
+ }
180
+ else if (e.key === " ") {
181
+ e.preventDefault();
182
+ toggle1x();
183
+ }
184
+ };
185
+ document.addEventListener("keydown", onKey);
186
+ return () => document.removeEventListener("keydown", onKey);
187
+ }, [zoomBy, resetView, toggle1x]);
188
+ const canPan = kind === "image" && scale > fitScale + 0.001;
32
189
  return ((0, jsx_runtime_1.jsxs)("div", { role: "dialog", "aria-modal": "true", onClick: (e) => {
33
190
  if (e.target === e.currentTarget)
34
191
  onClose();
35
192
  }, className: className ||
36
- "fixed inset-0 z-50 flex items-center justify-center bg-black/90 p-4 backdrop-blur-sm", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onClose, "aria-label": "Close", className: "absolute right-4 top-4 rounded-full bg-white/10 p-2 text-white transition-colors hover:bg-white/20", children: (0, jsx_runtime_1.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: (0, jsx_runtime_1.jsx)("path", { d: "M18 6L6 18M6 6l12 12" }) }) }), onPrev && ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: (e) => {
37
- e.stopPropagation();
38
- onPrev();
39
- }, "aria-label": "Previous", className: "absolute left-4 top-1/2 -translate-y-1/2 rounded-full bg-white/10 p-3 text-white transition-colors hover:bg-white/20", children: (0, jsx_runtime_1.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: (0, jsx_runtime_1.jsx)("path", { d: "M15 18l-6-6 6-6" }) }) })), onNext && ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: (e) => {
40
- e.stopPropagation();
41
- onNext();
42
- }, "aria-label": "Next", className: "absolute right-4 top-1/2 -translate-y-1/2 rounded-full bg-white/10 p-3 text-white transition-colors hover:bg-white/20", children: (0, jsx_runtime_1.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: (0, jsx_runtime_1.jsx)("path", { d: "M9 6l6 6-6 6" }) }) })), (0, jsx_runtime_1.jsxs)("div", { className: "flex max-h-full max-w-5xl flex-col items-center gap-3", children: [kind === "image" && url && (
193
+ "fixed inset-0 z-50 flex flex-col bg-black/95 backdrop-blur-sm", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between gap-3 border-b border-white/10 bg-black/40 px-4 py-2.5", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex min-w-0 items-center gap-3 text-xs text-white/70", children: [(0, jsx_runtime_1.jsx)("span", { className: "font-mono truncate max-w-md", children: media.fileName }), media.size ? ((0, jsx_runtime_1.jsx)("span", { className: "text-white/40", children: "\u00B7" })) : null, media.size ? (0, jsx_runtime_1.jsx)("span", { children: (0, utils_1.formatBytes)(media.size) }) : null, media.mimeType ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: "text-white/40", children: "\u00B7" }), (0, jsx_runtime_1.jsx)("span", { className: "font-mono text-white/40", children: media.mimeType })] })) : null] }), (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onClose, "aria-label": "Close", className: "rounded-full bg-white/10 p-1.5 text-white transition-colors hover:bg-white/20", children: (0, jsx_runtime_1.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: (0, jsx_runtime_1.jsx)("path", { d: "M18 6L6 18M6 6l12 12" }) }) })] }), (0, jsx_runtime_1.jsxs)("div", { ref: stageRef, onClick: (e) => {
194
+ if (e.target === e.currentTarget)
195
+ onClose();
196
+ }, onWheel: handleWheel, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: endDrag, onPointerLeave: endDrag, className: "relative flex flex-1 min-h-0 items-center justify-center overflow-hidden select-none", style: {
197
+ cursor: kind === "image"
198
+ ? isDragging
199
+ ? "grabbing"
200
+ : canPan
201
+ ? "grab"
202
+ : "default"
203
+ : "default",
204
+ }, children: [kind === "image" && url && (
43
205
  // eslint-disable-next-line @next/next/no-img-element
44
- (0, jsx_runtime_1.jsx)("img", { src: url, alt: media.alt ?? media.fileName, className: "max-h-[80vh] max-w-full rounded-lg object-contain shadow-2xl" })), kind === "video" && url && ((0, jsx_runtime_1.jsx)("video", { src: url, controls: true, autoPlay: true, className: "max-h-[80vh] max-w-full rounded-lg shadow-2xl" })), kind === "audio" && url && ((0, jsx_runtime_1.jsxs)("div", { className: "flex w-full max-w-md flex-col gap-3 rounded-lg bg-white/10 p-6 text-white", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-center text-sm font-medium", children: media.fileName }), (0, jsx_runtime_1.jsx)("audio", { src: url, controls: true, className: "w-full" })] })), kind !== "image" && kind !== "video" && kind !== "audio" && ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center gap-3 rounded-lg bg-white/10 p-8 text-white", children: [(0, jsx_runtime_1.jsxs)("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [(0, jsx_runtime_1.jsx)("path", { d: "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z" }), (0, jsx_runtime_1.jsx)("path", { d: "M14 2v6h6" })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm font-medium", children: media.fileName }), (0, jsx_runtime_1.jsx)("a", { href: url, download: media.fileName, target: "_blank", rel: "noreferrer", className: "rounded-md bg-white px-4 py-2 text-xs font-semibold text-black hover:bg-white/90", children: "Download" })] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 rounded-md bg-black/40 px-3 py-1.5 text-xs text-white/80", children: [(0, jsx_runtime_1.jsx)("span", { className: "font-mono truncate max-w-xs", children: media.fileName }), (0, jsx_runtime_1.jsx)("span", { children: "\u00B7" }), (0, jsx_runtime_1.jsx)("span", { children: (0, utils_1.formatBytes)(media.size ?? 0) }), media.mimeType && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { children: "\u00B7" }), (0, jsx_runtime_1.jsx)("span", { className: "font-mono opacity-70", children: media.mimeType })] }))] })] })] }));
206
+ (0, jsx_runtime_1.jsx)("img", { ref: imgRef, src: url, alt: media.alt ?? media.fileName, draggable: false, onLoad: handleImgLoad, onDoubleClick: toggle1x, className: "origin-center select-none", style: {
207
+ transform: `translate(${translate.x}px, ${translate.y}px) scale(${scale})`,
208
+ transition: isDragging ? "none" : "transform 0.18s ease-out",
209
+ maxWidth: "none",
210
+ maxHeight: "none",
211
+ willChange: "transform",
212
+ } })), kind === "video" && url && ((0, jsx_runtime_1.jsx)("video", { src: url, controls: true, autoPlay: true, className: "max-h-full max-w-full rounded-lg shadow-2xl" })), kind === "audio" && url && ((0, jsx_runtime_1.jsxs)("div", { className: "flex w-full max-w-md flex-col gap-3 rounded-lg bg-white/10 p-6 text-white", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-center text-sm font-medium", children: media.fileName }), (0, jsx_runtime_1.jsx)("audio", { src: url, controls: true, className: "w-full" })] })), kind !== "image" && kind !== "video" && kind !== "audio" && ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center gap-3 rounded-lg bg-white/10 p-8 text-white", children: [(0, jsx_runtime_1.jsxs)("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [(0, jsx_runtime_1.jsx)("path", { d: "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z" }), (0, jsx_runtime_1.jsx)("path", { d: "M14 2v6h6" })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm font-medium", children: media.fileName }), (0, jsx_runtime_1.jsx)("a", { href: url, download: media.fileName, target: "_blank", rel: "noreferrer", className: "rounded-md bg-white px-4 py-2 text-xs font-semibold text-black hover:bg-white/90", children: "Download" })] })), onPrev && ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: (e) => {
213
+ e.stopPropagation();
214
+ onPrev();
215
+ }, "aria-label": "Previous", className: "absolute left-4 top-1/2 -translate-y-1/2 rounded-full bg-white/10 p-3 text-white transition-colors hover:bg-white/20", children: (0, jsx_runtime_1.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: (0, jsx_runtime_1.jsx)("path", { d: "M15 18l-6-6 6-6" }) }) })), onNext && ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: (e) => {
216
+ e.stopPropagation();
217
+ onNext();
218
+ }, "aria-label": "Next", className: "absolute right-4 top-1/2 -translate-y-1/2 rounded-full bg-white/10 p-3 text-white transition-colors hover:bg-white/20", children: (0, jsx_runtime_1.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: (0, jsx_runtime_1.jsx)("path", { d: "M9 6l6 6-6 6" }) }) }))] }), kind === "image" && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-center gap-3 border-t border-white/10 bg-black/40 px-4 py-2.5", children: [(0, jsx_runtime_1.jsx)(ToolbarBtn, { onClick: () => zoomBy(1 / 1.2), title: "Zoom out (\u2212)", children: (0, jsx_runtime_1.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", width: "16", height: "16", children: [(0, jsx_runtime_1.jsx)("circle", { cx: "11", cy: "11", r: "7" }), (0, jsx_runtime_1.jsx)("path", { d: "M8 11h6M21 21l-4.3-4.3" })] }) }), (0, jsx_runtime_1.jsxs)("span", { className: "font-mono text-[11px] text-white/60 min-w-[3.5rem] text-center", children: [Math.round(scale * 100), "%"] }), (0, jsx_runtime_1.jsx)(ToolbarBtn, { onClick: () => zoomBy(1.2), title: "Zoom in (+)", children: (0, jsx_runtime_1.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", width: "16", height: "16", children: [(0, jsx_runtime_1.jsx)("circle", { cx: "11", cy: "11", r: "7" }), (0, jsx_runtime_1.jsx)("path", { d: "M8 11h6M11 8v6M21 21l-4.3-4.3" })] }) }), (0, jsx_runtime_1.jsx)("span", { className: "mx-2 h-5 w-px bg-white/15" }), (0, jsx_runtime_1.jsx)(ToolbarBtn, { onClick: resetView, title: "Fit (0)", children: (0, jsx_runtime_1.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", width: "16", height: "16", children: (0, jsx_runtime_1.jsx)("path", { d: "M4 9V4h5M20 9V4h-5M4 15v5h5M20 15v5h-5" }) }) }), (0, jsx_runtime_1.jsx)(ToolbarBtn, { onClick: toggle1x, title: "100% (Space)", children: (0, jsx_runtime_1.jsx)("span", { className: "font-mono text-[11px] font-medium", children: "1:1" }) })] }))] }));
219
+ }
220
+ function ToolbarBtn({ children, onClick, title, }) {
221
+ return ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onClick, title: title, "aria-label": title, className: "inline-flex size-8 items-center justify-center rounded-md text-white/80 transition-colors hover:bg-white/10 hover:text-white", children: children }));
45
222
  }
46
223
  //# sourceMappingURL=Lightbox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Lightbox.js","sourceRoot":"","sources":["../../../src/react/lib/Lightbox.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Lightbox.js","sourceRoot":"","sources":["../../../src/react/lib/Lightbox.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentroy-co/client-sdk",
3
- "version": "2.13.6",
3
+ "version": "2.13.8",
4
4
  "description": "TypeScript SDK + CLI for the Sentroy platform — mail, storage, env vault + React components.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -38,6 +38,21 @@
38
38
  "types": "./dist/vault/react.d.ts",
39
39
  "import": "./dist/vault/react.js",
40
40
  "require": "./dist/vault/react.js"
41
+ },
42
+ "./auth": {
43
+ "types": "./dist/auth/index.d.ts",
44
+ "import": "./dist/auth/index.js",
45
+ "require": "./dist/auth/index.js"
46
+ },
47
+ "./auth/admin": {
48
+ "types": "./dist/auth/admin/index.d.ts",
49
+ "import": "./dist/auth/admin/index.js",
50
+ "require": "./dist/auth/admin/index.js"
51
+ },
52
+ "./auth/react": {
53
+ "types": "./dist/auth/react/index.d.ts",
54
+ "import": "./dist/auth/react/index.js",
55
+ "require": "./dist/auth/react/index.js"
41
56
  }
42
57
  },
43
58
  "files": [
@@ -0,0 +1,191 @@
1
+ import { AuthHttp } from "../http"
2
+ import type { SentroyAuthUser } from "../types"
3
+
4
+ /**
5
+ * Server-side Sentroy Auth admin SDK. **Node only — apiKey browser'a
6
+ * koymayın**; bu sınıf Project'in master `aps_` token'ını taşır ve
7
+ * Sentroy üzerindeki user pool'a yetki vermez.
8
+ *
9
+ * Tipik kullanım: backend, kendi `/api/auth/...` proxy'sinde RP-spesifik
10
+ * authorization yapar, sonra `admin.users.get(...)` ile Sentroy'dan
11
+ * end-user'ı çeker. JWT verify de bu SDK üzerinden — tüm akış stateless.
12
+ */
13
+
14
+ export interface SentroyAuthAdminOptions {
15
+ authBaseUrl?: string
16
+ projectSlug: string
17
+ apiKey: string
18
+ }
19
+
20
+ export class SentroyAuthAdmin {
21
+ private readonly http: AuthHttp
22
+ private cachedJwks: { keys: Record<string, unknown>[] } | null = null
23
+
24
+ constructor(opts: SentroyAuthAdminOptions) {
25
+ this.http = new AuthHttp(opts)
26
+ }
27
+
28
+ // ─── User pool admin ──────────────────────────────────────────────────
29
+
30
+ users = {
31
+ list: (opts: {
32
+ limit?: number
33
+ skip?: number
34
+ emailVerified?: boolean
35
+ } = {}): Promise<{
36
+ items: SentroyAuthUser[]
37
+ pagination: { total: number; limit: number; skip: number }
38
+ }> => {
39
+ throw new Error(
40
+ "admin.users.list requires session-authenticated admin API; use dashboard /api/companies/[slug]/auth-projects/[id]/users instead. (v2 admin SDK will proxy this with stk_ tokens.)",
41
+ )
42
+ // NOTE Phase 5+: SDK admin endpoint'leri public path'lere taşınmadı;
43
+ // şu an `/api/companies/...` cookie-auth ile. v2'de `/api/v1/admin/...`
44
+ // RP token'ı ile authenticate eden ayrı public admin layer eklenir.
45
+ },
46
+ }
47
+
48
+ // ─── ID token verification ─────────────────────────────────────────────
49
+
50
+ /**
51
+ * Local verify — JWKS cache'lenir (5dk TTL), JWT signature kontrolü
52
+ * RS256 ile RP backend'inde stateless yapılır. `iss`/`aud` claim
53
+ * eşleşmesi de kontrol edilir.
54
+ */
55
+ async verifyIdToken(token: string): Promise<{
56
+ sub: string
57
+ email?: string
58
+ email_verified?: boolean
59
+ name?: string
60
+ picture?: string
61
+ iss: string
62
+ aud: string
63
+ iat: number
64
+ exp: number
65
+ }> {
66
+ const parts = token.split(".")
67
+ if (parts.length !== 3) {
68
+ throw new Error("Malformed JWT — expected three segments.")
69
+ }
70
+ const [headerB64, payloadB64, sigB64] = parts
71
+ const header = JSON.parse(decodeBase64Url(headerB64)) as {
72
+ alg?: string
73
+ kid?: string
74
+ }
75
+ if (header.alg !== "RS256") {
76
+ throw new Error("Only RS256 supported.")
77
+ }
78
+ const claims = JSON.parse(decodeBase64Url(payloadB64)) as {
79
+ exp?: number
80
+ iss?: string
81
+ aud?: string
82
+ }
83
+ if (typeof claims.exp !== "number" || claims.exp * 1000 < Date.now()) {
84
+ throw new Error("Token expired.")
85
+ }
86
+ // iss + aud check
87
+ const expectedIssSuffix = `/p/${this.http.projectSlug}`
88
+ if (typeof claims.iss !== "string" || !claims.iss.endsWith(expectedIssSuffix)) {
89
+ throw new Error("Issuer mismatch.")
90
+ }
91
+ // aud == project apiKeyPrefix (12 chars). API key first 12 = aud check.
92
+ if (
93
+ typeof claims.aud !== "string" ||
94
+ !this.http.apiKey?.startsWith(claims.aud)
95
+ ) {
96
+ throw new Error("Audience mismatch.")
97
+ }
98
+
99
+ const jwks = await this.fetchJwks()
100
+ const key = jwks.keys.find(
101
+ (k) => (k as { kid?: string }).kid === header.kid,
102
+ ) ?? jwks.keys[0]
103
+ if (!key) throw new Error("No public key in JWKS.")
104
+
105
+ await verifyRsaSignature({
106
+ data: `${headerB64}.${payloadB64}`,
107
+ sigB64,
108
+ jwk: key as JsonWebKey,
109
+ })
110
+
111
+ return claims as never
112
+ }
113
+
114
+ private async fetchJwks(): Promise<{ keys: Record<string, unknown>[] }> {
115
+ if (this.cachedJwks) return this.cachedJwks
116
+ const jwks = await this.http.request<{ keys: Record<string, unknown>[] }>(
117
+ "/jwks.json",
118
+ { method: "GET" },
119
+ )
120
+ this.cachedJwks = jwks
121
+ // 5dk cache — basit setTimeout invalidation
122
+ setTimeout(() => {
123
+ this.cachedJwks = null
124
+ }, 5 * 60 * 1000)
125
+ return jwks
126
+ }
127
+ }
128
+
129
+ // ─── Helpers ─────────────────────────────────────────────────────────────
130
+
131
+ function decodeBase64Url(s: string): string {
132
+ const padded = s.replace(/-/g, "+").replace(/_/g, "/")
133
+ const pad = padded.length % 4 === 0 ? "" : "=".repeat(4 - (padded.length % 4))
134
+ if (typeof atob === "function") {
135
+ const binary = atob(padded + pad)
136
+ const bytes = new Uint8Array(binary.length)
137
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)
138
+ return new TextDecoder().decode(bytes)
139
+ }
140
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
141
+ const B = (globalThis as any).Buffer
142
+ if (B) return B.from(padded + pad, "base64").toString("utf8")
143
+ throw new Error("No base64 decoder available")
144
+ }
145
+
146
+ function base64UrlToBytes(s: string): Uint8Array {
147
+ const padded = s.replace(/-/g, "+").replace(/_/g, "/")
148
+ const pad = padded.length % 4 === 0 ? "" : "=".repeat(4 - (padded.length % 4))
149
+ if (typeof atob === "function") {
150
+ const binary = atob(padded + pad)
151
+ const bytes = new Uint8Array(binary.length)
152
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)
153
+ return bytes
154
+ }
155
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
156
+ const B = (globalThis as any).Buffer
157
+ if (B) return new Uint8Array(B.from(padded + pad, "base64"))
158
+ throw new Error("No base64 decoder available")
159
+ }
160
+
161
+ async function verifyRsaSignature(input: {
162
+ data: string
163
+ sigB64: string
164
+ jwk: JsonWebKey
165
+ }): Promise<void> {
166
+ // Browser + modern Node (>=18) have crypto.subtle. Tek kod yolu.
167
+ const subtle =
168
+ typeof crypto !== "undefined" && crypto.subtle ? crypto.subtle : null
169
+ if (!subtle) {
170
+ throw new Error("Web Crypto unavailable — upgrade Node >= 18 or run in a browser.")
171
+ }
172
+ const key = await subtle.importKey(
173
+ "jwk",
174
+ input.jwk,
175
+ { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" },
176
+ false,
177
+ ["verify"],
178
+ )
179
+ // Web Crypto types want ArrayBuffer-backed BufferSource. TypeScript
180
+ // can't prove Uint8Array isn't SharedArrayBuffer-backed (DOM lib edge);
181
+ // bytes are created fresh from base64 decode so ArrayBuffer-safe — cast.
182
+ const sigBytes = base64UrlToBytes(input.sigB64) as Uint8Array
183
+ const dataBytes = new TextEncoder().encode(input.data) as Uint8Array
184
+ const ok = await subtle.verify(
185
+ { name: "RSASSA-PKCS1-v1_5" },
186
+ key,
187
+ sigBytes as unknown as ArrayBuffer,
188
+ dataBytes as unknown as ArrayBuffer,
189
+ )
190
+ if (!ok) throw new Error("Signature mismatch.")
191
+ }