Compare commits

...

80 Commits

Author SHA1 Message Date
public-glueops-renovatebot[bot]
863f0d221a chore(patch): update motion to 12.33.2 #patch 2026-02-11 20:20:53 +00:00
public-glueops-renovatebot[bot]
a40da0c23d chore(patch): update @types/react to 19.2.13 #patch (#650)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-11 20:04:26 +00:00
public-glueops-renovatebot[bot]
1c740da56d chore(patch): update @types/node to 25.2.2 #patch (#652)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-11 06:00:17 +00:00
public-glueops-renovatebot[bot]
0136c8ef78 chore(patch): update shadcn to 3.8.3 #patch (#642)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-07 17:45:19 +00:00
public-glueops-renovatebot[bot]
d4fdd85671 chore(patch): update @types/react to 19.2.11 #patch (#645)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-07 15:00:28 +00:00
public-glueops-renovatebot[bot]
5d3f0bfaf6 chore: lock file maintenance (#624)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:06:43 +00:00
public-glueops-renovatebot[bot]
3926bafa5c feat: update docker/login-action to v3.7.0 #minor (#623)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:03:13 +00:00
public-glueops-renovatebot[bot]
210a056fe6 feat: update github.com/aws/aws-sdk-go-v2/service/s3 to v1.96.0 #minor (#627)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:03:00 +00:00
public-glueops-renovatebot[bot]
b864187af5 feat: update typescript-eslint to 8.54.0 #minor (#618)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:02:44 +00:00
public-glueops-renovatebot[bot]
10725d9263 chore(lockfile): update motion-lockfile #patch (#633)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:02:30 +00:00
public-glueops-renovatebot[bot]
84d5575ea8 feat: update eslint-plugin-react-refresh to 0.5.0 #minor (#629)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:02:23 +00:00
public-glueops-renovatebot[bot]
b7b2c3c65d chore(patch): update motion to 12.29.3 #patch (#632)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:02:13 +00:00
public-glueops-renovatebot[bot]
94cd1ca2df chore(patch): update github.com/golang-jwt/jwt/v5 to v5.3.1 #patch (#626)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:01:59 +00:00
public-glueops-renovatebot[bot]
9379e8dd05 chore(patch): update golang to 1.25.7 #patch (#639)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:01:48 +00:00
public-glueops-renovatebot[bot]
e0b15f6b9e chore(patch): update github.com/go-chi/chi/v5 to v5.2.5 #patch (#641)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:01:42 +00:00
public-glueops-renovatebot[bot]
accf590d24 chore(patch): update @vitejs/plugin-react to 5.1.3 #patch (#631)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 23:01:21 +00:00
public-glueops-renovatebot[bot]
b910ff52ab feat: update @types/node to 25.2.1 #minor (#630)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 22:48:50 +00:00
public-glueops-renovatebot[bot]
1e498b309b chore(patch): update @types/react to 19.2.10 #patch (#619)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 22:40:45 +00:00
public-glueops-renovatebot[bot]
85601bcb84 chore(patch): update shadcn to 3.8.2 #patch (#635)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-05 11:32:21 +00:00
public-glueops-renovatebot[bot]
ce348a65ea chore(patch): update shadcn to 3.8.1 #patch (#634)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-03 11:59:38 +00:00
public-glueops-renovatebot[bot]
37153a6eed feat: update shadcn to 3.8.0 #minor (#628)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-02-03 00:52:13 +00:00
public-glueops-renovatebot[bot]
936891d110 chore(patch): update typescript-eslint to 8.53.1 #patch (#608)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:49:07 +00:00
public-glueops-renovatebot[bot]
965a5ed88b chore: lock file maintenance (#620)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:23:14 +00:00
public-glueops-renovatebot[bot]
c2b76f1dea chore(patch): update prettier to 3.8.1 #patch (#611)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:22:37 +00:00
public-glueops-renovatebot[bot]
5c9768b0b2 chore(patch): update @tanstack/react-query to 5.90.20 #patch (#598)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:22:22 +00:00
public-glueops-renovatebot[bot]
a02c29f333 chore(fallback): update golang (#607)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:22:16 +00:00
public-glueops-renovatebot[bot]
223d89bdd1 chore(patch): update @types/node to 25.0.10 #patch (#613)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:22:09 +00:00
public-glueops-renovatebot[bot]
411c98174a chore(lockfile): update motion-lockfile #patch (#614)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:22:03 +00:00
public-glueops-renovatebot[bot]
a7657368ed chore: lock file maintenance (#605)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:21:14 +00:00
public-glueops-renovatebot[bot]
134153c197 feat: update shadcn to 3.7.0 #minor (#603)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:20:44 +00:00
public-glueops-renovatebot[bot]
b4905b8c59 feat: update lucide-react to 0.563.0 #minor (#616)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:20:23 +00:00
public-glueops-renovatebot[bot]
f9dc0d4db5 chore(lockfile): update react-router-dom-lockfile #patch (#617)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:20:11 +00:00
public-glueops-renovatebot[bot]
3d6e53d24d chore(lockfile): update motion-lockfile #patch (#610)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:19:38 +00:00
public-glueops-renovatebot[bot]
2f6a382733 chore(lockfile): update motion-lockfile #patch (#606)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:19:27 +00:00
public-glueops-renovatebot[bot]
8261b5d702 chore(patch): update @types/react to 19.2.9 #patch (#609)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-27 18:01:27 +00:00
public-glueops-renovatebot[bot]
23415ead6d chore(patch): update @types/node to 25.0.9 #patch (#604)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-22 01:15:32 +00:00
public-glueops-renovatebot[bot]
ba8098acac feat: update prettier to 3.8.0 #minor (#600)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-21 18:51:23 +00:00
public-glueops-renovatebot[bot]
da5801cc6b chore: lock file maintenance (#596)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 17:33:44 +00:00
public-glueops-renovatebot[bot]
809c0930ae chore(patch): update golang to 1.25.6 #patch (#601)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 17:33:10 +00:00
public-glueops-renovatebot[bot]
17af4e8da4 chore(patch): update motion to 12.26.2 #patch (#592)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 17:33:05 +00:00
public-glueops-renovatebot[bot]
039fb04c97 chore(patch): update github.com/go-chi/chi/v5 to v5.2.4 #patch (#599)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 17:32:52 +00:00
public-glueops-renovatebot[bot]
335fd10fab chore(patch): update @types/react to 19.2.8 #patch (#590)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 17:32:43 +00:00
public-glueops-renovatebot[bot]
a3ec862e12 feat: update typescript-eslint to 8.53.0 #minor (#594)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 17:31:14 +00:00
public-glueops-renovatebot[bot]
66595daa4b chore(patch): update @types/node to 25.0.8 #patch (#602)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 17:16:31 +00:00
public-glueops-renovatebot[bot]
d6d1806907 chore(patch): update @types/node to 25.0.7 #patch (#597)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-16 08:30:02 +00:00
public-glueops-renovatebot[bot]
3c61f66c9a chore(patch): update @types/node to 25.0.6 #patch (#595)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-13 18:14:04 +00:00
public-glueops-renovatebot[bot]
0fb6fa3389 feat: update golang.org/x/crypto to v0.47.0 #minor (#593)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-13 04:35:28 +00:00
public-glueops-renovatebot[bot]
4cd9f77694 chore(patch): update github.com/aws/aws-sdk-go-v2 to v1.41.1 #patch (#588)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-13 04:23:26 +00:00
public-glueops-renovatebot[bot]
f6af0d970f chore(patch): update vite to 7.3.1 #patch (#578)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-13 04:02:47 +00:00
public-glueops-renovatebot[bot]
1138b346e3 chore: lock file maintenance (#587)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-13 04:02:17 +00:00
public-glueops-renovatebot[bot]
4e612652a2 chore(patch): update @types/node to 25.0.5 #patch (#589)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-13 03:24:39 +00:00
public-glueops-renovatebot[bot]
4127c0dd06 chore: lock file maintenance (#586)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-09 10:45:20 +00:00
public-glueops-renovatebot[bot]
8e97df134a chore(patch): update github.com/swaggo/swag/v2 to v2.0.0-rc5 #patch (#584)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-09 10:44:46 +00:00
public-glueops-renovatebot[bot]
636b500108 chore(patch): update shadcn to 3.6.3 #patch (#572)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-09 10:43:54 +00:00
public-glueops-renovatebot[bot]
2e3fd44b34 chore: lock file maintenance (#583)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-08 18:28:09 +00:00
public-glueops-renovatebot[bot]
2bfd8b0a78 chore: lock file maintenance (#581)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-08 17:14:27 +00:00
public-glueops-renovatebot[bot]
c7fb0bcf18 feat: update typescript-eslint to 8.52.0 #minor (#570)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-08 17:13:05 +00:00
public-glueops-renovatebot[bot]
c4a0fbd7b8 chore: lock file maintenance (#580)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-07 09:46:32 +00:00
public-glueops-renovatebot[bot]
8616336279 chore: lock file maintenance (#579)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-07 09:45:20 +00:00
public-glueops-renovatebot[bot]
d1ea3667e6 chore: lock file maintenance (#577)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-06 17:29:30 +00:00
allanice001
0f562ac5f4 ui fixes 2026-01-06 17:05:52 +00:00
allanice001
810218124e revert, but increase httprate 2026-01-06 10:11:42 +00:00
allanice001
5aff256377 fix import issue 2026-01-06 09:59:23 +00:00
Alanis
bdd6b61859 Remove rate limiting by IP from routes
Removed rate limiting middleware from the API routes.
2026-01-06 09:50:10 +00:00
public-glueops-renovatebot[bot]
42a86b22dd chore: lock file maintenance (#567)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-05 10:45:19 +00:00
public-glueops-renovatebot[bot]
b8cb1e1a2a chore: lock file maintenance (#566)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-05 10:11:13 +00:00
public-glueops-renovatebot[bot]
5a4ae19900 chore: lock file maintenance (#564)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-04 10:51:50 +00:00
public-glueops-renovatebot[bot]
d9db293894 chore: lock file maintenance (#563)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-04 08:27:53 +00:00
public-glueops-renovatebot[bot]
19d5ee7251 chore: lock file maintenance (#562)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-04 04:12:39 +00:00
public-glueops-renovatebot[bot]
6b91a5760b chore: lock file maintenance (#560)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-03 13:32:05 +00:00
public-glueops-renovatebot[bot]
bbd4c86013 chore: lock file maintenance (#559)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-02 14:40:46 +00:00
public-glueops-renovatebot[bot]
99ebcb11a3 chore: lock file maintenance (#558)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-02 13:44:37 +00:00
public-glueops-renovatebot[bot]
be1b35da3c feat: update typescript-eslint to 8.51.0 #minor (#540)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2026-01-01 17:09:21 +00:00
public-glueops-renovatebot[bot]
a6a296f283 chore: lock file maintenance (#556)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-31 23:27:07 +00:00
public-glueops-renovatebot[bot]
341ecf8b0a chore: lock file maintenance (#555)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-31 19:37:14 +00:00
public-glueops-renovatebot[bot]
92998015ec chore: lock file maintenance (#554)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-31 16:10:12 +00:00
public-glueops-renovatebot[bot]
9345c2761c chore: lock file maintenance (#553)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-31 15:08:55 +00:00
public-glueops-renovatebot[bot]
6944e5d027 chore: lock file maintenance (#552)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-31 06:14:14 +00:00
public-glueops-renovatebot[bot]
48b3bf5d3c chore: lock file maintenance (#551)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-31 06:13:11 +00:00
public-glueops-renovatebot[bot]
4c595db85e chore: lock file maintenance (#550)
Co-authored-by: public-glueops-renovatebot[bot] <186083205+public-glueops-renovatebot[bot]@users.noreply.github.com>
2025-12-31 05:42:43 +00:00
30 changed files with 5631 additions and 5290 deletions

View File

@@ -53,7 +53,7 @@ jobs:
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}

View File

@@ -1,7 +1,7 @@
#################################
# Builder: Go + Node in one
#################################
FROM golang:1.25.5-alpine@sha256:ac09a5f469f307e5da71e766b0bd59c9c49ea460a528cc3e6686513d64a6f1fb AS builder
FROM golang:1.25.7-alpine@sha256:81d49e1de26fa223b9ae0b4d5a4065ff8176a7d80aa5ef0bd9f2eee430afe4d7 AS builder
RUN apk add --no-cache \
bash git ca-certificates tzdata \

52
go.mod
View File

@@ -4,29 +4,29 @@ go 1.25.4
require (
github.com/alexedwards/argon2id v1.0.0
github.com/aws/aws-sdk-go-v2 v1.41.0
github.com/aws/aws-sdk-go-v2/config v1.32.6
github.com/aws/aws-sdk-go-v2/credentials v1.19.6
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.0
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0
github.com/aws/aws-sdk-go-v2 v1.41.1
github.com/aws/aws-sdk-go-v2/config v1.32.7
github.com/aws/aws-sdk-go-v2/credentials v1.19.7
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.1
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.0
github.com/aws/smithy-go v1.24.0
github.com/coreos/go-oidc/v3 v3.17.0
github.com/dyaksa/archer v1.1.5
github.com/fergusstrange/embedded-postgres v1.33.0
github.com/gin-gonic/gin v1.11.0
github.com/go-chi/chi/v5 v5.2.3
github.com/go-chi/chi/v5 v5.2.5
github.com/go-chi/cors v1.2.2
github.com/go-chi/httprate v0.15.0
github.com/go-playground/validator/v10 v10.30.1
github.com/golang-jwt/jwt/v5 v5.3.0
github.com/golang-jwt/jwt/v5 v5.3.1
github.com/google/uuid v1.6.0
github.com/joho/godotenv v1.5.1
github.com/rs/zerolog v1.34.0
github.com/sosedoff/pgweb v0.17.0
github.com/spf13/cobra v1.10.2
github.com/spf13/viper v1.21.0
github.com/swaggo/swag/v2 v2.0.0-rc4
golang.org/x/crypto v0.46.0
github.com/swaggo/swag/v2 v2.0.0-rc5
golang.org/x/crypto v0.47.0
golang.org/x/oauth2 v0.34.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/datatypes v1.2.7
@@ -40,19 +40,19 @@ require (
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.17 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16 // indirect
github.com/aws/aws-sdk-go-v2/service/signin v1.0.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.30.8 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.17 // indirect
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bytedance/sonic v1.14.0 // indirect
github.com/bytedance/sonic/loader v0.3.0 // indirect
@@ -113,7 +113,7 @@ require (
github.com/spf13/cast v1.10.0 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/sv-tools/openapi v0.2.1 // indirect
github.com/sv-tools/openapi v0.4.0 // indirect
github.com/tuvistavie/securerandom v0.0.0-20140719024926-15512123a948 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.0 // indirect
@@ -122,12 +122,12 @@ require (
go.uber.org/mock v0.5.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/arch v0.20.0 // indirect
golang.org/x/mod v0.30.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/mod v0.31.0 // indirect
golang.org/x/net v0.48.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.39.0 // indirect
golang.org/x/text v0.32.0 // indirect
golang.org/x/tools v0.39.0 // indirect
golang.org/x/sys v0.40.0 // indirect
golang.org/x/text v0.33.0 // indirect
golang.org/x/tools v0.40.0 // indirect
google.golang.org/protobuf v1.36.9 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gorm.io/driver/mysql v1.5.7 // indirect

56
go.sum
View File

@@ -12,42 +12,76 @@ github.com/alexedwards/argon2id v1.0.0 h1:wJzDx66hqWX7siL/SRUmgz3F8YMrd/nfX/xHHc
github.com/alexedwards/argon2id v1.0.0/go.mod h1:tYKkqIjzXvZdzPvADMWOEZ+l6+BD6CtBXMj5fnJppiw=
github.com/aws/aws-sdk-go-v2 v1.41.0 h1:tNvqh1s+v0vFYdA1xq0aOJH+Y5cRyZ5upu6roPgPKd4=
github.com/aws/aws-sdk-go-v2 v1.41.0/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
github.com/aws/aws-sdk-go-v2 v1.41.1 h1:ABlyEARCDLN034NhxlRUSZr4l71mh+T5KAeGh6cerhU=
github.com/aws/aws-sdk-go-v2 v1.41.1/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 h1:489krEF9xIGkOaaX3CE/Be2uWjiXrkCH6gUX+bZA/BU=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4/go.mod h1:IOAPF6oT9KCsceNTvvYMNHy0+kMF8akOjeDvPENWxp4=
github.com/aws/aws-sdk-go-v2/config v1.32.6 h1:hFLBGUKjmLAekvi1evLi5hVvFQtSo3GYwi+Bx4lpJf8=
github.com/aws/aws-sdk-go-v2/config v1.32.6/go.mod h1:lcUL/gcd8WyjCrMnxez5OXkO3/rwcNmvfno62tnXNcI=
github.com/aws/aws-sdk-go-v2/config v1.32.7 h1:vxUyWGUwmkQ2g19n7JY/9YL8MfAIl7bTesIUykECXmY=
github.com/aws/aws-sdk-go-v2/config v1.32.7/go.mod h1:2/Qm5vKUU/r7Y+zUk/Ptt2MDAEKAfUtKc1+3U1Mo3oY=
github.com/aws/aws-sdk-go-v2/credentials v1.19.6 h1:F9vWao2TwjV2MyiyVS+duza0NIRtAslgLUM0vTA1ZaE=
github.com/aws/aws-sdk-go-v2/credentials v1.19.6/go.mod h1:SgHzKjEVsdQr6Opor0ihgWtkWdfRAIwxYzSJ8O85VHY=
github.com/aws/aws-sdk-go-v2/credentials v1.19.7 h1:tHK47VqqtJxOymRrNtUXN5SP/zUTvZKeLx4tH6PGQc8=
github.com/aws/aws-sdk-go-v2/credentials v1.19.7/go.mod h1:qOZk8sPDrxhf+4Wf4oT2urYJrYt3RejHSzgAquYeppw=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16 h1:80+uETIWS1BqjnN9uJ0dBUaETh+P1XwFy5vwHwK5r9k=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16/go.mod h1:wOOsYuxYuB/7FlnVtzeBYRcjSRtQpAW0hCP7tIULMwo=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 h1:I0GyV8wiYrP8XpA70g1HBcQO1JlQxCMTW9npl5UbDHY=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17/go.mod h1:tyw7BOl5bBe/oqvoIeECFJjMdzXoa/dfVz3QQ5lgHGA=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 h1:rgGwPzb82iBYSvHMHXc8h9mRoOUBZIGFgKb9qniaZZc=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16/go.mod h1:L/UxsGeKpGoIj6DxfhOWHWQ/kGKcd4I1VncE4++IyKA=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 h1:xOLELNKGp2vsiteLsvLPwxC+mYmO6OZ8PYgiuPJzF8U=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17/go.mod h1:5M5CI3D12dNOtH3/mk6minaRwI2/37ifCURZISxA/IQ=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 h1:1jtGzuV7c82xnqOVfx2F0xmJcOw5374L7N6juGW6x6U=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16/go.mod h1:M2E5OQf+XLe+SZGmmpaI2yy+J326aFf6/+54PoxSANc=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 h1:WWLqlh79iO48yLkj1v3ISRNiv+3KdQoZ6JWyfcsyQik=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17/go.mod h1:EhG22vHRrvF8oXSTYStZhJc1aUgKtnJe+aOiFEV90cM=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16 h1:CjMzUs78RDDv4ROu3JnJn/Ig1r6ZD7/T2DXLLRpejic=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16/go.mod h1:uVW4OLBqbJXSHJYA9svT9BluSvvwbzLQ2Crf6UPzR3c=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.17 h1:JqcdRG//czea7Ppjb+g/n4o8i/R50aTBHkA7vu0lK+k=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.17/go.mod h1:CO+WeGmIdj/MlPel2KwID9Gt7CNq4M65HUfBW97liM0=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7 h1:DIBqIrJ7hv+e4CmIk2z3pyKT+3B6qVMgRsawHiR3qso=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7/go.mod h1:vLm00xmBke75UmpNvOcZQ/Q30ZFjbczeLFqGx5urmGo=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8 h1:Z5EiPIzXKewUQK0QTMkutjiaPVeVYXX7KIqhXu/0fXs=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8/go.mod h1:FsTpJtvC4U1fyDXk7c71XoDv3HlRm8V3NiYLeYLh5YE=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 h1:oHjJHeUy0ImIV0bsrX0X91GkV5nJAyv1l1CC9lnO0TI=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16/go.mod h1:iRSNGgOYmiYwSCXxXaKb9HfOEj40+oTKn8pTxMlYkRM=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 h1:RuNSMoozM8oXlgLG/n6WLaFGoea7/CddrCfIiSA+xdY=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17/go.mod h1:F2xxQ9TZz5gDWsclCtPQscGpP0VUOc8RqgFM3vDENmU=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16 h1:NSbvS17MlI2lurYgXnCOLvCFX38sBW4eiVER7+kkgsU=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16/go.mod h1:SwT8Tmqd4sA6G1qaGdzWCJN99bUmPGHfRwwq3G5Qb+A=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.17 h1:bGeHBsGZx0Dvu/eJC0Lh9adJa3M1xREcndxLNZlve2U=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.17/go.mod h1:dcW24lbU0CzHusTE8LLHhRLI42ejmINN8Lcr22bwh/g=
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.0 h1:80pDB3Tpmb2RCSZORrK9/3iQxsd+w6vSzVqpT1FGiwE=
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.0/go.mod h1:6EZUGGNLPLh5Unt30uEoA+KQcByERfXIkax9qrc80nA=
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.1 h1:1jIdwWOulae7bBLIgB36OZ0DINACb1wxM6wdGlx4eHE=
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.1/go.mod h1:tE2zGlMIlxWv+7Otap7ctRp3qeKqtnja7DZguj3Vu/Y=
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0 h1:MIWra+MSq53CFaXXAywB2qg9YvVZifkk6vEGl/1Qor0=
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0/go.mod h1:79S2BdqCJpScXZA2y+cpZuocWsjGjJINyXnOsf5DTz8=
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.1 h1:C2dUPSnEpy4voWFIq3JNd8gN0Y5vYGDo44eUE58a/p8=
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.1/go.mod h1:5jggDlZ2CLQhwJBiZJb4vfk4f0GxWdEDruWKEJ1xOdo=
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.0 h1:oeu8VPlOre74lBA/PMhxa5vewaMIMmILM+RraSyB8KA=
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.0/go.mod h1:5jggDlZ2CLQhwJBiZJb4vfk4f0GxWdEDruWKEJ1xOdo=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.4 h1:HpI7aMmJ+mm1wkSHIA2t5EaFFv5EFYXePW30p1EIrbQ=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.4/go.mod h1:C5RdGMYGlfM0gYq/tifqgn4EbyX99V15P2V3R+VHbQU=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 h1:VrhDvQib/i0lxvr3zqlUwLwJP4fpmpyD9wYG1vfSu+Y=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5/go.mod h1:k029+U8SY30/3/ras4G/Fnv/b88N4mAfliNn08Dem4M=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.8 h1:aM/Q24rIlS3bRAhTyFurowU8A0SMyGDtEOY/l/s/1Uw=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.8/go.mod h1:+fWt2UHSb4kS7Pu8y+BMBvJF0EWx+4H0hzNwtDNRTrg=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 h1:v6EiMvhEYBoHABfbGB4alOYmCIrcgyPPiBE1wZAEbqk=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9/go.mod h1:yifAsgBxgJWn3ggx70A3urX2AN49Y5sJTD1UQFlfqBw=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12 h1:AHDr0DaHIAo8c9t1emrzAlVDFp+iMMKnPdYy6XO4MCE=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12/go.mod h1:GQ73XawFFiWxyWXMHWfhiomvP3tXtdNar/fi8z18sx0=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13 h1:gd84Omyu9JLriJVCbGApcLzVR3XtmC4ZDPcAI6Ftvds=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13/go.mod h1:sTGThjphYE4Ohw8vJiRStAcu3rbjtXRsdNB0TvZ5wwo=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 h1:SciGFVNZ4mHdm7gpD1dgZYnCuVdX1s+lFTg4+4DOy70=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5/go.mod h1:iW40X4QBmUxdP+fZNOpfmkdMZqsovezbAeO+Ubiv2pk=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 h1:5fFjR/ToSOzB2OQ/XqWpZBmNvmP/pJ1jOWYlFDJTjRQ=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6/go.mod h1:qgFDZQSD/Kys7nJnVqYlWKnh0SSdMjAi0uSwON4wgYQ=
github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -87,6 +121,10 @@ github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE=
github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
github.com/go-chi/chi/v5 v5.2.4 h1:WtFKPHwlywe8Srng8j2BhOD9312j9cGUxG1SP4V2cR4=
github.com/go-chi/chi/v5 v5.2.4/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=
github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug=
github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=
github.com/go-chi/cors v1.2.2 h1:Jmey33TE+b+rB7fT8MUy1u0I4L+NARQlK6LhzKPSyQE=
github.com/go-chi/cors v1.2.2/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-chi/httprate v0.15.0 h1:j54xcWV9KGmPf/X4H32/aTH+wBlrvxL7P+SdnRqxh5g=
@@ -127,6 +165,8 @@ github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7Lk
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
@@ -263,8 +303,12 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/sv-tools/openapi v0.2.1 h1:ES1tMQMJFGibWndMagvdoo34T1Vllxr1Nlm5wz6b1aA=
github.com/sv-tools/openapi v0.2.1/go.mod h1:k5VuZamTw1HuiS9p2Wl5YIDWzYnHG6/FgPOSFXLAhGg=
github.com/sv-tools/openapi v0.4.0 h1:UhD9DVnGox1hfTePNclpUzUFgos57FvzT2jmcAuTOJ4=
github.com/sv-tools/openapi v0.4.0/go.mod h1:kD/dG+KP0+Fom1r6nvcj/ORtLus8d8enXT6dyRZDirE=
github.com/swaggo/swag/v2 v2.0.0-rc4 h1:SZ8cK68gcV6cslwrJMIOqPkJELRwq4gmjvk77MrvHvY=
github.com/swaggo/swag/v2 v2.0.0-rc4/go.mod h1:Ow7Y8gF16BTCDn8YxZbyKn8FkMLRUHekv1kROJZpbvE=
github.com/swaggo/swag/v2 v2.0.0-rc5 h1:fK7d6ET9rrEsdB8IyuwXREWMcyQN3N7gawGFbbrjgHk=
github.com/swaggo/swag/v2 v2.0.0-rc5/go.mod h1:kCL8Fu4Zl8d5tB2Bgj96b8wRowwrwk175bZHXfuGVFI=
github.com/tuvistavie/securerandom v0.0.0-20140719024926-15512123a948 h1:yL0l/u242MzDP6D0B5vGC+wxm5WRY+alQZy+dJk3bFI=
github.com/tuvistavie/securerandom v0.0.0-20140719024926-15512123a948/go.mod h1:a06d/M1pxWi51qiSrfGMHaEydtuXT06nha8N2aNQuXk=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
@@ -292,10 +336,14 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
@@ -304,6 +352,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -328,6 +378,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -343,12 +395,16 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=

View File

@@ -37,7 +37,7 @@ func NewRouter(db *gorm.DB, jobs *bg.Jobs, studio http.Handler) http.Handler {
r.Use(middleware.Recoverer)
r.Use(SecurityHeaders)
r.Use(requestBodyLimit(10 << 20))
r.Use(httprate.LimitByIP(100, 1*time.Minute))
r.Use(httprate.LimitByIP(1000, 1*time.Minute))
r.Use(middleware.StripSlashes)
allowed := getAllowedOrigins()

View File

@@ -503,7 +503,6 @@ func ListRecordSets(db *gorm.DB) http.HandlerFunc {
}
}
// GetRecordSet godoc
//
// @ID GetRecordSet
@@ -517,35 +516,35 @@ func ListRecordSets(db *gorm.DB) http.HandlerFunc {
// @Failure 404 {string} string "not found"
// @Router /dns/records/{id} [get]
func GetRecordSet(db *gorm.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
orgID, ok := httpmiddleware.OrgIDFrom(r.Context())
if !ok {
utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID")
return
}
return func(w http.ResponseWriter, r *http.Request) {
orgID, ok := httpmiddleware.OrgIDFrom(r.Context())
if !ok {
utils.WriteError(w, http.StatusForbidden, "org_required", "specify X-Org-ID")
return
}
id, err := uuid.Parse(chi.URLParam(r, "id"))
if err != nil {
utils.WriteError(w, http.StatusBadRequest, "bad_id", "invalid UUID")
return
}
id, err := uuid.Parse(chi.URLParam(r, "id"))
if err != nil {
utils.WriteError(w, http.StatusBadRequest, "bad_id", "invalid UUID")
return
}
var row models.RecordSet
if err := db.
Joins("Domain").
Where(`record_sets.id = ? AND "Domain"."organization_id" = ?`, id, orgID).
First(&row).Error; err != nil {
var row models.RecordSet
if err := db.
Joins("Domain").
Where(`record_sets.id = ? AND "Domain"."organization_id" = ?`, id, orgID).
First(&row).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
utils.WriteError(w, http.StatusNotFound, "not_found", "record set not found")
return
}
utils.WriteError(w, http.StatusInternalServerError, "db_error", err.Error())
return
}
if errors.Is(err, gorm.ErrRecordNotFound) {
utils.WriteError(w, http.StatusNotFound, "not_found", "record set not found")
return
}
utils.WriteError(w, http.StatusInternalServerError, "db_error", err.Error())
return
}
utils.WriteJSON(w, http.StatusOK, recordOut(&row))
}
utils.WriteJSON(w, http.StatusOK, recordOut(&row))
}
}
// CreateRecordSet godoc

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

4186
internal/web/dist/assets/index-GteqH5KT.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -5,9 +5,9 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AutoGlue</title>
<script type="module" crossorigin src="/assets/index-CyGsiYei.js"></script>
<link rel="modulepreload" crossorigin href="/assets/react-Dt2M6tWj.js">
<link rel="stylesheet" crossorigin href="/assets/index-VHZG0dIU.css">
<script type="module" crossorigin src="/assets/index-GteqH5KT.js"></script>
<link rel="modulepreload" crossorigin href="/assets/react-v1TLhXpT.js">
<link rel="stylesheet" crossorigin href="/assets/index-Cdjh6IZW.css">
</head>
<body>
<div id="root"></div>

Binary file not shown.

Binary file not shown.

View File

@@ -1,2 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88"
height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -46,14 +46,14 @@
"date-fns": "^4.1.0",
"embla-carousel-react": "^8.6.0",
"input-otp": "^1.4.2",
"lucide-react": "^0.562.0",
"lucide-react": "^0.563.0",
"motion": "^12.23.26",
"next-themes": "^0.4.6",
"rapidoc": "^9.3.8",
"react": "^19.2.3",
"react-day-picker": "^9.13.0",
"react-dom": "^19.2.3",
"react-hook-form": "^7.69.0",
"react-hook-form": "^7.70.0",
"react-icons": "^5.5.0",
"react-resizable-panels": "^3.0.6",
"react-router-dom": "^7.11.0",
@@ -67,20 +67,20 @@
"devDependencies": {
"@eslint/js": "9.39.2",
"@ianvs/prettier-plugin-sort-imports": "4.7.0",
"@types/node": "25.0.3",
"@types/react": "19.2.7",
"@types/node": "25.2.2",
"@types/react": "19.2.13",
"@types/react-dom": "19.2.3",
"@vitejs/plugin-react": "5.1.2",
"@vitejs/plugin-react": "5.1.3",
"eslint": "9.39.2",
"eslint-plugin-react-hooks": "7.0.1",
"eslint-plugin-react-refresh": "0.4.26",
"eslint-plugin-react-refresh": "0.5.0",
"globals": "16.5.0",
"prettier": "3.7.4",
"prettier": "3.8.1",
"prettier-plugin-tailwindcss": "0.7.2",
"shadcn": "3.6.2",
"shadcn": "3.8.3",
"tw-animate-css": "1.4.0",
"typescript": "5.9.3",
"typescript-eslint": "8.50.1",
"vite": "7.3.0"
"typescript-eslint": "8.54.0",
"vite": "7.3.1"
}
}

View File

@@ -68,6 +68,10 @@ const AWS_ALLOWED_SERVICES = ["route53", "s3", "ec2", "iam", "rds", "dynamodb"]
type AwsSvc = (typeof AWS_ALLOWED_SERVICES)[number]
// -------------------- Schemas --------------------
// Zod v4 gotchas you hit:
// - .partial() cannot be used if the object contains refinements/effects (often true once you have transforms/refines).
// - .extend() cannot overwrite keys after refinements (requires .safeExtend()).
// Easiest fix: define CREATE and UPDATE schemas separately (no .partial(), no post-refinement .extend()).
const createCredentialSchema = z
.object({
@@ -91,6 +95,16 @@ const createCredentialSchema = z
secret: z.any(),
})
.superRefine((val, ctx) => {
// scope required unless provider scope
if (val.scope_kind !== "provider" && !val.scope) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["scope"],
message: `scope is required`,
})
}
// AWS scope checks
if (val.credential_provider === "aws") {
if (val.scope_kind === "service") {
const svc = (val.scope as any)?.service
@@ -112,23 +126,25 @@ const createCredentialSchema = z
})
}
}
if (val.kind === "aws_access_key") {
const sk = val.secret ?? {}
const id = sk.access_key_id
if (typeof id !== "string" || !/^[A-Z0-9]{20}$/.test(id)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["secret"],
message: `access_key_id must be 20 chars (A-Z0-9)`,
})
}
if (typeof sk.secret_access_key !== "string" || sk.secret_access_key.length < 10) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["secret"],
message: `secret_access_key is required`,
})
}
}
// secret requiredness by kind (create always validates)
if (val.kind === "aws_access_key") {
const sk = val.secret ?? {}
const id = sk.access_key_id
if (typeof id !== "string" || !/^[A-Z0-9]{20}$/.test(id)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["secret"],
message: `access_key_id must be 20 chars (A-Z0-9)`,
})
}
if (typeof sk.secret_access_key !== "string" || sk.secret_access_key.length < 10) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["secret"],
message: `secret_access_key is required`,
})
}
}
@@ -142,6 +158,7 @@ const createCredentialSchema = z
})
}
}
if (val.kind === "basic_auth") {
const s = val.secret ?? {}
if (!s.username || !s.password) {
@@ -152,6 +169,7 @@ const createCredentialSchema = z
})
}
}
if (val.kind === "oauth2") {
const s = val.secret ?? {}
if (!s.client_id || !s.client_secret || !s.refresh_token) {
@@ -162,30 +180,144 @@ const createCredentialSchema = z
})
}
}
if (val.scope_kind !== "provider" && !val.scope) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["scope"],
message: `scope is required`,
})
}
})
type CreateCredentialValues = z.input<typeof createCredentialSchema>
const updateCredentialSchema = createCredentialSchema.partial().extend({
name: z.string().min(1, "Name is required").max(100).optional(),
})
// UPDATE schema: all fields optional, and validations are "patch-friendly".
const updateCredentialSchema = z
.object({
credential_provider: z
.enum(["aws", "cloudflare", "hetzner", "digitalocean", "generic"])
.optional(),
kind: z.enum(["aws_access_key", "api_token", "basic_auth", "oauth2"]).optional(),
schema_version: z.number().optional(),
name: z.string().min(1, "Name is required").max(100).optional(),
scope_kind: z.enum(["provider", "service", "resource"]).optional(),
scope_version: z.number().optional(),
scope: z.any().optional(),
// allow "" so your form can keep empty strings; buildUpdateBody will drop them
account_id: z.string().optional().or(z.literal("")),
region: z.string().optional().or(z.literal("")),
secret: z.any().optional(),
})
.superRefine((val, ctx) => {
// If scope_kind is being changed to non-provider, require scope in the patch
if (typeof val.scope_kind !== "undefined") {
if (val.scope_kind !== "provider" && !val.scope) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["scope"],
message: `scope is required`,
})
}
}
// AWS scope checks only if we have enough info
if (val.credential_provider === "aws") {
if (val.scope_kind === "service" && typeof val.scope !== "undefined") {
const svc = (val.scope as any)?.service
if (!AWS_ALLOWED_SERVICES.includes(svc)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["scope"],
message: `For AWS service scope, "service" must be one of: ${AWS_ALLOWED_SERVICES.join(", ")}`,
})
}
}
if (val.scope_kind === "resource" && typeof val.scope !== "undefined") {
const arn = (val.scope as any)?.arn
if (typeof arn !== "string" || !arn.startsWith("arn:")) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["scope"],
message: `For AWS resource scope, "arn" must start with "arn:"`,
})
}
}
}
// Secret validation on update:
// - only validate if rotating secret OR changing kind
// - if rotating secret but kind is NOT provided, skip kind-specific checks (backend can validate)
const rotatingSecret = typeof val.secret !== "undefined"
const changingKind = typeof val.kind !== "undefined"
if (!rotatingSecret && !changingKind) return
if (!val.kind) return
if (val.kind === "aws_access_key") {
const sk = val.secret ?? {}
const id = sk.access_key_id
if (typeof id !== "string" || !/^[A-Z0-9]{20}$/.test(id)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["secret"],
message: `access_key_id must be 20 chars (A-Z0-9)`,
})
}
if (typeof sk.secret_access_key !== "string" || sk.secret_access_key.length < 10) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["secret"],
message: `secret_access_key is required`,
})
}
}
if (val.kind === "api_token") {
const token = (val.secret ?? {}).token
if (!token) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["secret"],
message: `token is required`,
})
}
}
if (val.kind === "basic_auth") {
const s = val.secret ?? {}
if (!s.username || !s.password) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["secret"],
message: `username and password are required`,
})
}
}
if (val.kind === "oauth2") {
const s = val.secret ?? {}
if (!s.client_id || !s.client_secret || !s.refresh_token) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["secret"],
message: `client_id, client_secret, and refresh_token are required`,
})
}
}
})
type UpdateCredentialValues = z.input<typeof updateCredentialSchema>
// -------------------- Helpers --------------------
function pretty(obj: unknown) {
try {
return JSON.stringify(JSON.parse(obj as string), null, 2)
if (obj == null) return ""
if (typeof obj === "string") {
try {
return JSON.stringify(JSON.parse(obj), null, 2)
} catch {
return obj
}
}
return JSON.stringify(obj, null, 2)
} catch {
return ""
}
}
function extractErr(e: any): string {
const raw = (e as any)?.body ?? (e as any)?.response ?? (e as any)?.message
if (typeof raw === "string") return raw
@@ -252,9 +384,9 @@ function buildCreateBody(v: CreateCredentialValues) {
}
// Build exact PATCH body (only provided fields)
function buildUpdateBody(v: z.infer<typeof updateCredentialSchema>) {
function buildUpdateBody(v: UpdateCredentialValues) {
const body: any = {}
const keys: (keyof typeof v)[] = [
const keys: (keyof UpdateCredentialValues)[] = [
"name",
"account_id",
"region",
@@ -316,7 +448,7 @@ export const CredentialPage = () => {
// Update
const updateMutation = useMutation({
mutationFn: (payload: { id: string; body: z.infer<typeof updateCredentialSchema> }) =>
mutationFn: (payload: { id: string; body: UpdateCredentialValues }) =>
credentialsApi.updateCredential(payload.id, buildUpdateBody(payload.body)),
onSuccess: async () => {
await qc.invalidateQueries({ queryKey: ["credentials"] })
@@ -362,7 +494,7 @@ export const CredentialPage = () => {
mode: "onBlur",
})
const editForm = useForm<z.input<typeof updateCredentialSchema>>({
const editForm = useForm<UpdateCredentialValues>({
resolver: zodResolver(updateCredentialSchema),
defaultValues: {},
mode: "onBlur",
@@ -371,7 +503,8 @@ export const CredentialPage = () => {
function openEdit(row: any) {
setEditingId(row.id)
editForm.reset({
provider: row.provider,
// FIX: correct key (was "provider" in your original)
credential_provider: row.credential_provider,
kind: row.kind,
schema_version: row.schema_version ?? 1,
name: row.name,
@@ -380,7 +513,7 @@ export const CredentialPage = () => {
account_id: row.account_id ?? "",
region: row.region ?? "",
scope: row.scope ?? (row.scope_kind === "provider" ? {} : undefined),
secret: undefined,
secret: undefined, // keep existing unless user rotates
} as any)
setUseRawEditSecretJSON(false)
setEditOpen(true)
@@ -394,7 +527,7 @@ export const CredentialPage = () => {
return items.filter((c: any) =>
[
c.name,
c.provider,
c.credential_provider,
c.kind,
c.scope_kind,
c.account_id,
@@ -436,6 +569,7 @@ export const CredentialPage = () => {
function ensureCreateDefaultsForSecret() {
if (useRawSecretJSON) return
if (credential_provider === "aws" && kind === "aws_access_key") {
const s = createForm.getValues("secret") ?? {}
setCreateSecret({
@@ -459,7 +593,7 @@ export const CredentialPage = () => {
}
function onChangeCreateScopeKind(next: "provider" | "service" | "resource") {
createForm.setValue("scope_kind", next)
createForm.setValue("scope_kind", next, { shouldDirty: true, shouldValidate: true })
if (next === "provider") setCreateScope({})
if (next === "service") setCreateScope({ service: "route53" as AwsSvc })
if (next === "resource") setCreateScope({ arn: "" })
@@ -905,6 +1039,7 @@ export const CredentialPage = () => {
client_secret: e.target.value,
})
}
placeholder="••••••••••"
/>
)}
/>
@@ -933,7 +1068,6 @@ export const CredentialPage = () => {
)}
<DialogFooter className="gap-2">
{/* Preview Create button */}
<Button
type="button"
variant="secondary"
@@ -1260,9 +1394,7 @@ export const CredentialPage = () => {
<FormItem>
<FormLabel>Rotate Secret (JSON)</FormLabel>
<Textarea
value={
typeof field.value === "string" ? field.value : pretty(field.value ?? {})
}
value={typeof field.value === "string" ? field.value : pretty(field.value)}
onChange={(e) => {
try {
field.onChange(JSON.parse(e.target.value))
@@ -1281,7 +1413,6 @@ export const CredentialPage = () => {
)}
<DialogFooter className="gap-2">
{/* Preview Update button */}
<Button
type="button"
variant="secondary"

View File

@@ -128,6 +128,10 @@ const credLabel = (c: DtoCredentialOut) => {
}
// ---------- zod schemas ----------
// IMPORTANT (Zod v4):
// - `.partial()` cannot be used on object schemas containing refinements/effects.
// Your schemas contain effects via `.transform(...)` and refinements via `.superRefine(...)` / `.refine(...)`,
// so we define UPDATE schemas explicitly instead of using `.partial()`.
const createDomainSchema = z.object({
domain_name: z
@@ -144,8 +148,22 @@ const createDomainSchema = z.object({
})
type CreateDomainValues = z.input<typeof createDomainSchema>
const updateDomainSchema = createDomainSchema.partial()
type UpdateDomainValues = z.infer<typeof updateDomainSchema>
// Update: all optional; replicate the normalization safely
const updateDomainSchema = z.object({
domain_name: z
.string()
.min(1, "Domain is required")
.max(253)
.transform((s) => s.trim().replace(/\.$/, "").toLowerCase())
.optional(),
credential_id: z.string().uuid("Pick a credential").optional(),
zone_id: z
.string()
.optional()
.or(z.literal(""))
.transform((v) => (v ? v.trim() : undefined)),
})
type UpdateDomainValues = z.input<typeof updateDomainSchema>
const ttlSchema = z
.union([
@@ -182,7 +200,42 @@ const createRecordSchema = z
})
type CreateRecordValues = z.input<typeof createRecordSchema>
const updateRecordSchema = createRecordSchema.partial()
// Update: all optional. Only enforce "values required"/"CNAME exactly one" if valuesCsv is present.
// Only validate ttl if present (ttlSchema already optional).
const updateRecordSchema = z
.object({
name: z
.string()
.min(1, "Name required")
.max(253)
.transform((s) => s.trim().replace(/\.$/, "").toLowerCase())
.optional(),
type: z.enum(rrtypes as [string, ...string[]]).optional(),
ttl: ttlSchema,
valuesCsv: z.string().optional(),
})
.superRefine((vals, ctx) => {
const hasValues = typeof vals.valuesCsv !== "undefined"
if (!hasValues) return
const arr = parseCommaList(vals.valuesCsv ?? "")
if (arr.length === 0) {
ctx.addIssue({
code: "custom",
path: ["valuesCsv"],
message: "At least one value is required",
})
}
// We can only enforce CNAME rule if `type` is provided in patch (or you can enforce always if you want).
if (vals.type === "CNAME" && arr.length !== 1) {
ctx.addIssue({
code: "custom",
path: ["valuesCsv"],
message: "CNAME requires exactly one value",
})
}
})
type UpdateRecordValues = z.input<typeof updateRecordSchema>
// ---------- main ----------
@@ -224,12 +277,9 @@ export const DnsPage = () => {
const r53Credentials = useMemo(() => (credentialQ.data ?? []).filter(isR53), [credentialQ.data])
useEffect(() => {
const setSelectedDns = () => {
if (!selected && domainsQ.data && domainsQ.data.length) {
setSelected(domainsQ.data[0]!)
}
if (!selected && domainsQ.data && domainsQ.data.length) {
setSelected(domainsQ.data[0]!)
}
setSelectedDns()
}, [domainsQ.data, selected])
const filteredDomains = useMemo(() => {
@@ -237,7 +287,7 @@ export const DnsPage = () => {
if (!filter.trim()) return list
const f = filter.toLowerCase()
return list.filter((d) =>
[d.domain_name, d.zone_id, d.status, d.domain_name]
[d.domain_name, d.zone_id, d.status]
.filter(Boolean)
.map((x) => String(x).toLowerCase())
.some((s) => s.includes(f))
@@ -271,6 +321,7 @@ export const DnsPage = () => {
const editDomainForm = useForm<UpdateDomainValues>({
resolver: zodResolver(updateDomainSchema),
defaultValues: {},
})
const openEditDomain = (d: DtoDomainResponse) => {
@@ -283,10 +334,20 @@ export const DnsPage = () => {
setEditDomOpen(true)
}
// Build PATCH body (dont send empty strings)
const buildUpdateDomainBody = (vals: UpdateDomainValues): DtoUpdateDomainRequest => {
const body: any = {}
if (typeof vals.domain_name !== "undefined") body.domain_name = vals.domain_name
if (typeof vals.credential_id !== "undefined" && vals.credential_id !== "")
body.credential_id = vals.credential_id
if (typeof vals.zone_id !== "undefined" && vals.zone_id !== "") body.zone_id = vals.zone_id
return body as DtoUpdateDomainRequest
}
const updateDomainMut = useMutation({
mutationFn: (vals: UpdateDomainValues) => {
if (!selected) throw new Error("No domain selected")
return dnsApi.updateDomain(selected.id!, vals as unknown as DtoUpdateDomainRequest)
return dnsApi.updateDomain(selected.id!, buildUpdateDomainBody(vals))
},
onSuccess: async () => {
toast.success("Domain updated")
@@ -338,7 +399,6 @@ export const DnsPage = () => {
const body: DtoCreateRecordSetRequest = {
name: vals.name,
type: vals.type,
// omit ttl when empty/undefined
...(vals.ttl ? { ttl: vals.ttl as unknown as number } : {}),
values: parseCommaList(vals.valuesCsv ?? ""),
}
@@ -356,6 +416,7 @@ export const DnsPage = () => {
const editRecForm = useForm<UpdateRecordValues>({
resolver: zodResolver(updateRecordSchema),
defaultValues: {},
})
const openEditRecord = (r: DtoRecordSetResponse) => {
@@ -374,15 +435,12 @@ export const DnsPage = () => {
mutationFn: async (vals: UpdateRecordValues) => {
if (!editingRecord) throw new Error("No record selected")
const body: DtoUpdateRecordSetRequest = {}
if (vals.name !== undefined) body.name = vals.name
if (vals.type !== undefined) body.type = vals.type
if (vals.ttl !== undefined && vals.ttl !== null) {
// if blank string came through it would have been filtered; when undefined, omit
body.ttl = vals.ttl as unknown as number | undefined
}
if (vals.valuesCsv !== undefined) {
body.values = parseCommaList(vals.valuesCsv)
}
if (typeof vals.name !== "undefined") body.name = vals.name
if (typeof vals.type !== "undefined") body.type = vals.type
if (typeof vals.ttl !== "undefined") body.ttl = vals.ttl as unknown as number | undefined
if (typeof vals.valuesCsv !== "undefined") body.values = parseCommaList(vals.valuesCsv)
return dnsApi.updateRecordSetsByDomain(editingRecord.id!, body)
},
onSuccess: async () => {
@@ -556,7 +614,14 @@ export const DnsPage = () => {
</td>
<td className="px-3 py-2">
<div className="flex items-center justify-end gap-2">
<Button size="icon" variant="ghost" onClick={() => openEditDomain(d)}>
<Button
size="icon"
variant="ghost"
onClick={(e) => {
e.stopPropagation()
openEditDomain(d)
}}
>
<Pencil className="h-4 w-4" />
</Button>
<AlertDialog>
@@ -650,10 +715,7 @@ export const DnsPage = () => {
render={({ field }) => (
<FormItem>
<FormLabel>Type</FormLabel>
<Select
onValueChange={field.onChange}
defaultValue={field.value as string}
>
<Select onValueChange={field.onChange} value={field.value as string}>
<FormControl>
<SelectTrigger>
<SelectValue />
@@ -969,7 +1031,7 @@ export const DnsPage = () => {
render={({ field }) => (
<FormItem>
<FormLabel>Type</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value as string}>
<Select onValueChange={field.onChange} value={field.value as string}>
<FormControl>
<SelectTrigger>
<SelectValue />

View File

@@ -53,13 +53,17 @@ type Role = (typeof ROLE_OPTIONS)[number]
const STATUS = ["pending", "provisioning", "ready", "failed"] as const
type Status = (typeof STATUS)[number]
// ---------- Zod schemas ----------
// Zod v4: `.partial()` cannot be used on schemas with refinements/effects.
// createServerSchema has a refinement, so define updateServerSchema explicitly.
const createServerSchema = z
.object({
hostname: z.string().trim().max(60, "Max 60 chars"),
public_ip_address: z.string().trim().optional().or(z.literal("")),
private_ip_address: z.string().trim().min(1, "Private IP address required"),
role: z.enum(ROLE_OPTIONS),
ssh_key_id: z.uuid("Pick a valid SSH key"),
ssh_key_id: z.string().uuid("Pick a valid SSH key"),
ssh_user: z.string().trim().min(1, "SSH user is required"),
status: z.enum(STATUS).default("pending"),
})
@@ -69,8 +73,33 @@ const createServerSchema = z
)
type CreateServerInput = z.input<typeof createServerSchema>
const updateServerSchema = createServerSchema.partial()
type UpdateServerValues = z.infer<typeof updateServerSchema>
// Patch-friendly update schema:
// - all fields optional
// - only enforce "public ip required" if role is being set to bastion in the patch
const updateServerSchema = z
.object({
hostname: z.string().trim().max(60, "Max 60 chars").optional(),
public_ip_address: z.string().trim().optional().or(z.literal("")),
private_ip_address: z.string().trim().min(1, "Private IP address required").optional(),
role: z.enum(ROLE_OPTIONS).optional(),
ssh_key_id: z.string().uuid("Pick a valid SSH key").optional(),
ssh_user: z.string().trim().min(1, "SSH user is required").optional(),
status: z.enum(STATUS).optional(),
})
.superRefine((v, ctx) => {
// If updating role to bastion, require public_ip_address in the patch
if (v.role === "bastion") {
const pub = typeof v.public_ip_address === "string" ? v.public_ip_address.trim() : ""
if (!pub) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["public_ip_address"],
message: "Public IP required for bastion",
})
}
}
})
type UpdateServerValues = z.input<typeof updateServerSchema>
function StatusBadge({ status }: { status: Status }) {
const v =
@@ -88,6 +117,27 @@ function StatusBadge({ status }: { status: Status }) {
)
}
// Build PATCH body: omit undefined and empty strings (so optional inputs can be cleared in UI without sending "")
function buildUpdateBody(values: UpdateServerValues) {
const body: any = {}
const keys: (keyof UpdateServerValues)[] = [
"hostname",
"public_ip_address",
"private_ip_address",
"role",
"ssh_key_id",
"ssh_user",
"status",
]
for (const k of keys) {
const v = values[k]
if (typeof v === "undefined") continue
if (v === "") continue
body[k] = v
}
return body
}
export const ServerPage = () => {
const [filter, setFilter] = useState<string>("")
const [createOpen, setCreateOpen] = useState<boolean>(false)
@@ -180,13 +230,12 @@ export const ServerPage = () => {
})
const roleIsBastionU = watchedRoleUpdate === "bastion"
const pubUpdate = watchedPublicIpAddressUpdate?.trim() ?? ""
const needPubUpdate = roleIsBastionU && pubUpdate === ""
const updateMut = useMutation({
mutationFn: ({ id, values }: { id: string; values: UpdateServerValues }) =>
serversApi.updateServer(id, values as any),
serversApi.updateServer(id, buildUpdateBody(values) as any),
onSuccess: async () => {
await qc.invalidateQueries({ queryKey: ["servers"] })
setUpdateOpen(false)
@@ -279,7 +328,7 @@ export const ServerPage = () => {
</div>
<Select
value={roleFilter || "all"} // map "" -> "all" for the UI
value={roleFilter || "all"}
onValueChange={(v) => setRoleFilter(v === "all" ? "" : (v as Role))}
>
<SelectTrigger className="w-36">
@@ -296,14 +345,14 @@ export const ServerPage = () => {
</Select>
<Select
value={statusFilter || "all"} // map "" -> "all" for the UI
value={statusFilter || "all"}
onValueChange={(v) => setStatusFilter(v === "all" ? "" : (v as Status))}
>
<SelectTrigger className="w-40">
<SelectValue placeholder="Status (all)" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">All statuses</SelectItem> {/* sentinel */}
<SelectItem value="all">All statuses</SelectItem>
{STATUS.map((s) => (
<SelectItem key={s} value={s}>
{s}

File diff suppressed because it is too large Load Diff