create-aphex 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/dist/index.js +9 -88
  2. package/package.json +4 -4
  3. package/templates/base/.dockerignore +0 -44
  4. package/templates/base/.env.example +0 -38
  5. package/templates/base/CHANGELOG.md +0 -124
  6. package/templates/base/Dockerfile +0 -69
  7. package/templates/base/README.md +0 -147
  8. package/templates/base/aphex.config.ts +0 -45
  9. package/templates/base/docker-compose.yml +0 -31
  10. package/templates/base/drizzle/0000_tiny_redwing.sql +0 -226
  11. package/templates/base/drizzle/meta/0000_snapshot.json +0 -1379
  12. package/templates/base/drizzle/meta/_journal.json +0 -13
  13. package/templates/base/drizzle.config.ts +0 -17
  14. package/templates/base/package.json +0 -81
  15. package/templates/base/prod.docker-compose.yml +0 -61
  16. package/templates/base/src/app.css +0 -32
  17. package/templates/base/src/app.d.ts +0 -26
  18. package/templates/base/src/app.html +0 -11
  19. package/templates/base/src/hooks.server.ts +0 -52
  20. package/templates/base/src/lib/assets/favicon.svg +0 -5
  21. package/templates/base/src/lib/auth-client.ts +0 -19
  22. package/templates/base/src/lib/index.ts +0 -1
  23. package/templates/base/src/lib/schemaTypes/index.ts +0 -11
  24. package/templates/base/src/lib/schemaTypes/post.ts +0 -47
  25. package/templates/base/src/lib/server/auth/better-auth/instance.ts +0 -183
  26. package/templates/base/src/lib/server/auth/index.ts +0 -25
  27. package/templates/base/src/lib/server/auth/instance.ts +0 -7
  28. package/templates/base/src/lib/server/auth/service.ts +0 -486
  29. package/templates/base/src/lib/server/cache/index.ts +0 -10
  30. package/templates/base/src/lib/server/db/auth-schema.ts +0 -86
  31. package/templates/base/src/lib/server/db/cms-schema.ts +0 -23
  32. package/templates/base/src/lib/server/db/index.ts +0 -55
  33. package/templates/base/src/lib/server/db/schema.ts +0 -3
  34. package/templates/base/src/lib/server/email/components/EmailLayout.svelte +0 -24
  35. package/templates/base/src/lib/server/email/components/EmailVerification.svelte +0 -26
  36. package/templates/base/src/lib/server/email/components/Invitation.svelte +0 -30
  37. package/templates/base/src/lib/server/email/components/PasswordReset.svelte +0 -28
  38. package/templates/base/src/lib/server/email/index.ts +0 -28
  39. package/templates/base/src/lib/server/email/invitation-hook.ts +0 -56
  40. package/templates/base/src/lib/server/email/renderer.ts +0 -13
  41. package/templates/base/src/lib/server/email/templates/email-verification.ts +0 -8
  42. package/templates/base/src/lib/server/email/templates/invitation.ts +0 -8
  43. package/templates/base/src/lib/server/email/templates/password-reset.ts +0 -7
  44. package/templates/base/src/lib/server/services/organization.ts +0 -68
  45. package/templates/base/src/lib/server/storage/index.ts +0 -28
  46. package/templates/base/src/lib/stores/activeTab.svelte.ts +0 -14
  47. package/templates/base/src/lib/utils/imageBuilder.ts +0 -3
  48. package/templates/base/src/lib/utils/slug.ts +0 -33
  49. package/templates/base/src/routes/(protected)/admin/+layout.server.ts +0 -86
  50. package/templates/base/src/routes/(protected)/admin/+layout.svelte +0 -78
  51. package/templates/base/src/routes/(protected)/admin/+page.server.ts +0 -60
  52. package/templates/base/src/routes/(protected)/admin/+page.svelte +0 -34
  53. package/templates/base/src/routes/(protected)/admin/organizations/+page.server.ts +0 -39
  54. package/templates/base/src/routes/(protected)/admin/organizations/+page.svelte +0 -31
  55. package/templates/base/src/routes/(protected)/admin/organizations/_components/CreateOrganization.svelte +0 -141
  56. package/templates/base/src/routes/(protected)/admin/organizations/_components/OrganizationsList.svelte +0 -102
  57. package/templates/base/src/routes/(protected)/admin/settings/+layout.server.ts +0 -42
  58. package/templates/base/src/routes/(protected)/admin/settings/+layout.svelte +0 -116
  59. package/templates/base/src/routes/(protected)/admin/settings/+page.server.ts +0 -16
  60. package/templates/base/src/routes/(protected)/admin/settings/+page.svelte +0 -32
  61. package/templates/base/src/routes/(protected)/admin/settings/_components/AccountSettings.svelte +0 -177
  62. package/templates/base/src/routes/(protected)/admin/settings/_components/ApiKeysSettings.svelte +0 -472
  63. package/templates/base/src/routes/(protected)/admin/settings/_components/OrganizationsSettings.svelte +0 -182
  64. package/templates/base/src/routes/(protected)/admin/settings/account/+page.server.ts +0 -25
  65. package/templates/base/src/routes/(protected)/admin/settings/account/+page.svelte +0 -23
  66. package/templates/base/src/routes/(protected)/admin/settings/api-keys/+page.server.ts +0 -54
  67. package/templates/base/src/routes/(protected)/admin/settings/api-keys/+page.svelte +0 -14
  68. package/templates/base/src/routes/(protected)/admin/settings/members/+page.server.ts +0 -31
  69. package/templates/base/src/routes/(protected)/admin/settings/members/+page.svelte +0 -338
  70. package/templates/base/src/routes/(protected)/admin/settings/roles/+page.server.ts +0 -17
  71. package/templates/base/src/routes/(protected)/admin/settings/roles/+page.svelte +0 -339
  72. package/templates/base/src/routes/+layout.svelte +0 -12
  73. package/templates/base/src/routes/+page.svelte +0 -2
  74. package/templates/base/src/routes/api/[...slug]/+server.ts +0 -35
  75. package/templates/base/src/routes/api/instance-settings/+server.ts +0 -70
  76. package/templates/base/src/routes/api/invitations/+server.ts +0 -54
  77. package/templates/base/src/routes/api/invitations/[id]/accept/+server.ts +0 -54
  78. package/templates/base/src/routes/api/invitations/[id]/reject/+server.ts +0 -49
  79. package/templates/base/src/routes/api/settings/api-keys/+server.ts +0 -57
  80. package/templates/base/src/routes/api/settings/api-keys/[id]/+server.ts +0 -53
  81. package/templates/base/src/routes/god-mode/+layout.server.ts +0 -32
  82. package/templates/base/src/routes/god-mode/+layout.svelte +0 -155
  83. package/templates/base/src/routes/god-mode/+page.server.ts +0 -10
  84. package/templates/base/src/routes/god-mode/+page.svelte +0 -32
  85. package/templates/base/src/routes/god-mode/_components/CreateOrganization.svelte +0 -141
  86. package/templates/base/src/routes/god-mode/_components/OrganizationsList.svelte +0 -169
  87. package/templates/base/src/routes/god-mode/organizations/+page.server.ts +0 -43
  88. package/templates/base/src/routes/god-mode/organizations/+page.svelte +0 -74
  89. package/templates/base/src/routes/invitations/+page.server.ts +0 -48
  90. package/templates/base/src/routes/invitations/+page.svelte +0 -264
  91. package/templates/base/src/routes/invite/[token]/+page.server.ts +0 -59
  92. package/templates/base/src/routes/invite/[token]/+page.svelte +0 -109
  93. package/templates/base/src/routes/login/+page.server.ts +0 -14
  94. package/templates/base/src/routes/login/+page.svelte +0 -332
  95. package/templates/base/src/routes/media/[id]/[filename]/+server.ts +0 -3
  96. package/templates/base/src/routes/reset-password/[token]/+page.server.ts +0 -15
  97. package/templates/base/src/routes/reset-password/[token]/+page.svelte +0 -179
  98. package/templates/base/src/routes/verify-email/+page.svelte +0 -41
  99. package/templates/base/static/images/aphex-darkmode.png +0 -0
  100. package/templates/base/static/images/aphex-lightmode.png +0 -0
  101. package/templates/base/static/robots.txt +0 -3
  102. package/templates/base/svelte.config.js +0 -19
  103. package/templates/base/tsconfig.json +0 -20
  104. package/templates/base/vite.config.ts +0 -146
@@ -1,332 +0,0 @@
1
- <script lang="ts">
2
- import { authClient } from '$lib/auth-client';
3
- import { goto } from '$app/navigation';
4
- import { page } from '$app/state';
5
- import { Button } from '@aphexcms/ui/shadcn/button';
6
- import { Input } from '@aphexcms/ui/shadcn/input';
7
- import { Label } from '@aphexcms/ui/shadcn/label';
8
- import * as Card from '@aphexcms/ui/shadcn/card';
9
- import { resolve } from '$app/paths';
10
-
11
- type Mode = 'signin' | 'signup' | 'reset-password';
12
-
13
- // Read initial mode + prefilled email from URL (used by invite flow)
14
- const initialMode: Mode = page.url.searchParams.get('mode') === 'signup' ? 'signup' : 'signin';
15
- const prefilledEmail = page.url.searchParams.get('email') ?? '';
16
- // When the email came from an invite link, lock the field so users can't
17
- // sign up with an address that won't match the invitation.
18
- const emailLocked = prefilledEmail.length > 0 && initialMode === 'signup';
19
-
20
- let email = $state(prefilledEmail);
21
- let password = $state('');
22
- let error = $state('');
23
- let loading = $state(false);
24
- let mode: Mode = $state(initialMode);
25
- let resetSuccess = $state('');
26
- let signupSuccess = $state(false);
27
-
28
- // Get callback URL for post-login redirect (used by invite flow)
29
- let callbackUrl = $derived(page.url.searchParams.get('callbackUrl'));
30
-
31
- // Error messages mapping
32
- const errorMessages: Record<string, string> = {
33
- session_expired: 'Your session has expired. Please log in again.',
34
- no_organization:
35
- 'No organization found. Please contact an administrator to be invited to an organization.',
36
- unauthorized: 'You do not have permission to access this resource.',
37
- kicked_from_org:
38
- 'Your access to the organization has been revoked. Please contact your administrator.',
39
- no_session: 'Please log in to continue.'
40
- };
41
-
42
- // Read error from URL reactively (Svelte 5)
43
- $effect(() => {
44
- const errorCode = page.url.searchParams.get('error');
45
- if (errorCode && errorMessages[errorCode]) {
46
- error = errorMessages[errorCode];
47
- // Clear error from URL
48
- const url = new URL(window.location.href);
49
- url.searchParams.delete('error');
50
- window.history.replaceState({}, '', url);
51
- }
52
- });
53
-
54
- async function handleSubmit(e: SubmitEvent) {
55
- e.preventDefault();
56
- error = '';
57
- resetSuccess = '';
58
- loading = true;
59
-
60
- try {
61
- if (mode === 'reset-password') {
62
- const response = await fetch('/api/user/request-password-reset', {
63
- method: 'POST',
64
- headers: {
65
- 'Content-Type': 'application/json'
66
- },
67
- body: JSON.stringify({
68
- email,
69
- redirectTo: `${window.location.origin}/reset-password`
70
- })
71
- });
72
-
73
- const result = await response.json();
74
-
75
- if (!response.ok || result.error) {
76
- error = result.message || 'Failed to send reset email';
77
- } else {
78
- resetSuccess = 'Check your email for the password reset link';
79
- }
80
- } else if (mode === 'signin') {
81
- const result = await authClient.signIn.email({
82
- email,
83
- password
84
- });
85
-
86
- if (result.error) {
87
- if (result.error.code === 'EMAIL_NOT_VERIFIED') {
88
- error =
89
- 'Please verify your email address before signing in. Check your inbox for a verification link.';
90
- } else {
91
- error = result.error.message || 'Failed to sign in';
92
- }
93
- } else {
94
- goto(callbackUrl || '/admin');
95
- }
96
- } else {
97
- // mode === 'signup'
98
- const result = await authClient.signUp.email({
99
- email,
100
- password,
101
- name: email.split('@')[0] // Use email username as name
102
- });
103
-
104
- if (result.error) {
105
- error = result.error.message || 'Failed to sign up';
106
- } else {
107
- // Email verification is enabled — show confirmation instead of redirecting
108
- signupSuccess = true;
109
- }
110
- }
111
- } catch (err) {
112
- error = err instanceof Error ? err.message : 'An error occurred';
113
- } finally {
114
- loading = false;
115
- }
116
- }
117
-
118
- function setMode(newMode: Mode) {
119
- mode = newMode;
120
- error = '';
121
- resetSuccess = '';
122
- }
123
- </script>
124
-
125
- <svelte:head>
126
- <title>{mode === 'signin' ? 'Aphex CMS - Sign In' : 'Aphex CMS - Sign Up'}</title>
127
- <meta
128
- name="description"
129
- content={mode === 'signin'
130
- ? 'Sign in to your Aphex CMS dashboard to manage your content and organizations.'
131
- : 'Create a new account to get started with Aphex CMS and manage your content.'}
132
- />
133
- </svelte:head>
134
-
135
- <div class="bg-muted/40 flex min-h-screen items-center justify-center px-4 py-12">
136
- <div class="w-full max-w-md">
137
- <Card.Root class="shadow-lg">
138
- <Card.Header class="space-y-1">
139
- <Card.Title class="text-center text-2xl font-bold">
140
- {mode === 'reset-password'
141
- ? 'Reset Password'
142
- : mode === 'signin'
143
- ? 'Sign In'
144
- : 'Create Account'}
145
- </Card.Title>
146
- <Card.Description class="text-center">
147
- {mode === 'reset-password'
148
- ? 'Enter your email to receive a reset link'
149
- : mode === 'signin'
150
- ? 'Access your CMS dashboard'
151
- : 'Get started with Aphex CMS'}
152
- </Card.Description>
153
- </Card.Header>
154
-
155
- <Card.Content>
156
- {#if signupSuccess}
157
- <div class="space-y-4">
158
- <div class="rounded-lg border border-green-500/50 bg-green-500/10 p-4 text-center">
159
- <p class="font-medium text-green-700 dark:text-green-400">
160
- Account created! Check your email to verify your address.
161
- </p>
162
- <p class="text-muted-foreground mt-2 text-sm">
163
- We sent a verification link to <strong>{email}</strong>
164
- </p>
165
- </div>
166
- <Button
167
- variant="outline"
168
- class="w-full"
169
- onclick={() => {
170
- signupSuccess = false;
171
- setMode('signin');
172
- }}
173
- >
174
- Back to Sign In
175
- </Button>
176
- </div>
177
- {:else}
178
- <form onsubmit={handleSubmit} class="space-y-4">
179
- <!-- Success Alert -->
180
- {#if resetSuccess}
181
- <div class="rounded-lg border border-green-500/50 bg-green-500/10 p-3">
182
- <p class="text-sm font-medium text-green-700 dark:text-green-400">{resetSuccess}</p>
183
- </div>
184
- {/if}
185
-
186
- <!-- Error Alert -->
187
- {#if error}
188
- <div class="border-destructive/50 bg-destructive/10 rounded-lg border p-3">
189
- <p class="text-destructive text-sm font-medium">{error}</p>
190
- </div>
191
- {/if}
192
-
193
- <!-- Email Field -->
194
- <div class="space-y-2">
195
- <Label for="email">Email</Label>
196
- <Input
197
- id="email"
198
- type="email"
199
- placeholder="you@example.com"
200
- bind:value={email}
201
- required
202
- autocomplete="email"
203
- readonly={emailLocked}
204
- />
205
- {#if emailLocked}
206
- <p class="text-muted-foreground text-xs">Locked to match your invitation.</p>
207
- {/if}
208
- </div>
209
-
210
- <!-- Password Field (hidden in reset mode) -->
211
- {#if mode !== 'reset-password'}
212
- <div class="space-y-2">
213
- <div class="flex items-center justify-between">
214
- <Label for="password">Password</Label>
215
- {#if mode === 'signin'}
216
- <button
217
- type="button"
218
- class="text-primary text-xs hover:underline"
219
- onclick={() => setMode('reset-password')}
220
- >
221
- Forgot password?
222
- </button>
223
- {/if}
224
- </div>
225
- <Input
226
- id="password"
227
- type="password"
228
- placeholder="••••••••"
229
- bind:value={password}
230
- required
231
- autocomplete={mode === 'signin' ? 'current-password' : 'new-password'}
232
- />
233
- {#if mode === 'signup'}
234
- <p class="text-muted-foreground text-xs">Must be at least 8 characters long</p>
235
- {/if}
236
- </div>
237
- {/if}
238
-
239
- <!-- Submit Button -->
240
- <Button type="submit" class="w-full" disabled={loading}>
241
- {#if loading}
242
- <svg
243
- class="mr-2 h-4 w-4 animate-spin"
244
- xmlns="http://www.w3.org/2000/svg"
245
- fill="none"
246
- viewBox="0 0 24 24"
247
- >
248
- <circle
249
- class="opacity-25"
250
- cx="12"
251
- cy="12"
252
- r="10"
253
- stroke="currentColor"
254
- stroke-width="4"
255
- ></circle>
256
- <path
257
- class="opacity-75"
258
- fill="currentColor"
259
- d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
260
- ></path>
261
- </svg>
262
- {/if}
263
- {mode === 'reset-password'
264
- ? 'Send Reset Link'
265
- : mode === 'signin'
266
- ? 'Sign In'
267
- : 'Sign Up'}
268
- </Button>
269
-
270
- <!-- Back to Sign In (in reset mode) -->
271
- {#if mode === 'reset-password'}
272
- <Button
273
- type="button"
274
- variant="ghost"
275
- class="w-full"
276
- onclick={() => setMode('signin')}
277
- >
278
- ← Back to Sign In
279
- </Button>
280
- {/if}
281
- </form>
282
- {/if}
283
- </Card.Content>
284
-
285
- <Card.Footer class="flex flex-col space-y-4">
286
- {#if !signupSuccess && mode !== 'reset-password'}
287
- <div class="relative">
288
- <div class="absolute inset-0 flex items-center">
289
- <span class="w-full border-t"></span>
290
- </div>
291
- <div class="relative flex justify-center text-xs uppercase">
292
- <span class="bg-card text-muted-foreground px-2">
293
- {mode === 'signin' ? 'New to Aphex?' : 'Already have an account?'}
294
- </span>
295
- </div>
296
- </div>
297
-
298
- <Button
299
- type="button"
300
- variant="outline"
301
- class="w-full"
302
- onclick={() => setMode(mode === 'signin' ? 'signup' : 'signin')}
303
- >
304
- {mode === 'signin' ? 'Create an account' : 'Sign in instead'}
305
- </Button>
306
- {/if}
307
- </Card.Footer>
308
- </Card.Root>
309
-
310
- <!-- Footer -->
311
- <p class="text-muted-foreground mt-6 text-center text-xs">Aphex CMS - Built with SvelteKit</p>
312
-
313
- <!-- Footer Logo -->
314
- <div class="mt-2 flex justify-center opacity-20">
315
- <svg
316
- class="h-8 w-8 fill-black dark:fill-white"
317
- version="1.1"
318
- xmlns="http://www.w3.org/2000/svg"
319
- viewBox="0 0 512 512"
320
- >
321
- <path
322
- d="M0 0 C17.1474496 14.16905616 25.92496627 35.45820085 34.56640625 55.4140625 C35.34334316 57.19720923 36.12053079 58.98024674 36.89794922 60.76318359 C51.78722595 94.97195072 66.32335778 129.32882671 80.31640625 163.9140625 C80.6444928 164.72450012 80.97257935 165.53493774 81.31060791 166.36993408 C99.98913061 212.53216334 117.78569191 259.01293728 134.00390625 306.1015625 C134.36190811 307.13669983 134.36190811 307.13669983 134.72714233 308.19274902 C137.32766526 315.72906515 139.80262285 323.3004011 142.1171875 330.9296875 C142.43800545 331.95940926 142.43800545 331.95940926 142.76530457 333.00993347 C145.2565569 341.39135358 146.09964488 351.05219488 142.44140625 359.23046875 C139.92789443 362.992009 136.34564423 365.89944351 132.31640625 367.9140625 C124.8558052 368.61421121 118.36839373 368.62364314 112.31640625 363.9140625 C105.53664487 356.69699976 100.652558 348.68983785 95.94140625 340.0390625 C90.47619491 330.29913602 84.93335438 322.05287151 77.31640625 313.9140625 C75.27331056 311.57880549 73.26394666 309.2152832 71.25390625 306.8515625 C70.24519648 305.67152884 69.23608749 304.49183631 68.2265625 303.3125 C67.73816895 302.74112305 67.24977539 302.16974609 66.74658203 301.58105469 C65.40017275 300.01169952 64.04454028 298.45078423 62.6875 296.890625 C48.81582552 280.69615056 38.44623629 261.89870442 27.89111328 243.45849609 C-8.42360388 178.69858879 -8.42360388 178.69858879 -68.08203125 137.78515625 C-79.11186673 135.11741947 -89.899608 136.09230489 -99.68359375 141.9140625 C-115.46806791 152.47947666 -122.3076261 172.13261849 -126.43359375 189.7890625 C-126.73185059 191.06136719 -126.73185059 191.06136719 -127.03613281 192.359375 C-130.16760015 206.71148601 -131.06828893 221.08194412 -130.99609375 235.7265625 C-130.9939386 236.51966827 -130.99178345 237.31277405 -130.98956299 238.12991333 C-131.31394288 266.6844263 -131.31394288 266.6844263 -123.23828125 293.5859375 C-112.95312656 315.60340432 -111.26097095 345.34400812 -119.5 368.0390625 C-124.86779615 381.07766965 -132.78250397 390.79435644 -145.68359375 396.9140625 C-155.27731384 400.41943083 -164.20346687 401.56551213 -174.37109375 401.4140625 C-176.32958252 401.39702271 -176.32958252 401.39702271 -178.32763672 401.37963867 C-197.70054192 400.99323331 -215.16231823 397.0095896 -230.68359375 384.9140625 C-231.37066406 384.41519531 -232.05773437 383.91632813 -232.765625 383.40234375 C-244.80767188 373.97296976 -251.15090869 358.63090674 -253.68359375 343.9140625 C-253.9270261 339.66653687 -253.91464574 335.41789154 -253.93359375 331.1640625 C-253.96453125 329.45089844 -253.96453125 329.45089844 -253.99609375 327.703125 C-254.00125 326.58164062 -254.00640625 325.46015625 -254.01171875 324.3046875 C-254.02106445 323.29438477 -254.03041016 322.28408203 -254.04003906 321.24316406 C-253.25260131 313.88871121 -250.02140677 307.08532381 -247.0859375 300.359375 C-246.73986954 299.55749252 -246.39380157 298.75561005 -246.0372467 297.9294281 C-245.29136983 296.20150738 -244.54396437 294.47424582 -243.79516602 292.74758911 C-241.75797546 288.04789133 -239.73451175 283.34229198 -237.7109375 278.63671875 C-237.0834108 277.17808662 -237.0834108 277.17808662 -236.44320679 275.68998718 C-232.12759637 265.64489937 -227.89599701 255.56528394 -223.68359375 245.4765625 C-223.31303864 244.58933502 -222.94248352 243.70210754 -222.56069946 242.78799438 C-221.05624911 239.1852842 -219.55230259 235.58236459 -218.04930115 231.97904968 C-215.45620988 225.7624217 -212.85713855 219.54832537 -210.25390625 213.3359375 C-199.87599396 188.56875674 -189.53860671 163.78483086 -179.21582031 138.99462891 C-176.70326253 132.96093438 -174.18966694 126.92767262 -171.67578125 120.89453125 C-171.2632309 119.90436005 -170.85068054 118.91418884 -170.42562866 117.89401245 C-168.35461551 112.92351005 -166.28304289 107.95324201 -164.21044922 102.98339844 C-160.33953189 93.69973915 -156.47385511 84.41400336 -152.62658691 75.12051392 C-150.82992691 70.78139762 -149.03030349 66.44351312 -147.23046875 62.10571289 C-146.38199036 60.05847127 -145.53492768 58.01064218 -144.68945312 55.9621582 C-140.72547669 46.35880091 -136.72273166 36.78723512 -132.3203125 27.375 C-132.00310242 26.69433975 -131.68589233 26.0136795 -131.35906982 25.31239319 C-123.25124472 8.26154126 -109.39227096 -6.16254505 -91.68359375 -13.0859375 C-59.99340229 -22.6620319 -26.67593546 -20.59334511 0 0 Z "
323
- transform="translate(308.68359375,64.0859375)"
324
- />
325
- <path
326
- d="M0 0 C18.24717952 9.79342293 31.4582424 26.28742033 37.6171875 45.97265625 C39.90862161 58.10790422 38.62948747 76.77026254 32.3125 87.5625 C31.23887442 89.06398132 30.13305826 90.54284625 29 92 C28.04867187 93.39798828 28.04867187 93.39798828 27.078125 94.82421875 C22.05477616 102.1158627 16.59613089 108.96607145 8 112 C-4.55244493 113.74100692 -12.66496084 107.03937869 -22.140625 99.87890625 C-25.14482573 97.61370274 -28.2068393 95.46853473 -31.33056641 93.37231445 C-44.35072813 84.61921656 -53.55106508 73.69367426 -57 58 C-59.27762162 41.63399726 -53.36243485 19.43955677 -44.1875 5.9375 C-32.8352893 -8.66127096 -15.43371672 -7.37348527 0 0 Z "
327
- transform="translate(254,240)"
328
- />
329
- </svg>
330
- </div>
331
- </div>
332
- </div>
@@ -1,3 +0,0 @@
1
- // Clean Sanity-style asset URLs: /media/{id}/{filename}
2
- // Re-export from Aphex CMS Core
3
- export { serveAssetCDN as GET } from '@aphexcms/cms-core/server';
@@ -1,15 +0,0 @@
1
- import { redirect } from '@sveltejs/kit';
2
- import type { PageServerLoad } from '../../(protected)/admin/$types';
3
-
4
- export const load: PageServerLoad = async ({ locals, request }) => {
5
- const { aphexCMS } = locals;
6
-
7
- const session = await aphexCMS.auth?.getSession(request, aphexCMS.databaseAdapter);
8
-
9
- // If user is already authenticated, redirect to admin
10
- if (session?.session) {
11
- throw redirect(302, '/admin');
12
- }
13
-
14
- return {};
15
- };
@@ -1,179 +0,0 @@
1
- <script lang="ts">
2
- import { authClient } from '$lib/auth-client';
3
- import { goto } from '$app/navigation';
4
- import { page } from '$app/state';
5
- import { Button } from '@aphexcms/ui/shadcn/button';
6
- import { Input } from '@aphexcms/ui/shadcn/input';
7
- import { Label } from '@aphexcms/ui/shadcn/label';
8
- import * as Card from '@aphexcms/ui/shadcn/card';
9
- import { resolve } from '$app/paths';
10
-
11
- let newPassword = $state('');
12
- let confirmPassword = $state('');
13
- let error = $state('');
14
- let success = $state(false);
15
- let loading = $state(false);
16
- let token = $state('');
17
-
18
- // Get token from SvelteKit route params
19
- $effect(() => {
20
- const errorParam = page.url.searchParams.get('error');
21
-
22
- if (errorParam === 'INVALID_TOKEN') {
23
- error = 'Invalid or expired reset link. Please request a new password reset.';
24
- } else if (page.params.token) {
25
- // Token from dynamic route parameter
26
- token = page.params.token;
27
- } else {
28
- error = 'No reset token provided. Please request a new password reset.';
29
- }
30
- });
31
-
32
- async function handleSubmit(e: SubmitEvent) {
33
- e.preventDefault();
34
- error = '';
35
- loading = true;
36
-
37
- if (newPassword !== confirmPassword) {
38
- error = 'Passwords do not match';
39
- loading = false;
40
- return;
41
- }
42
-
43
- if (newPassword.length < 8) {
44
- error = 'Password must be at least 8 characters long';
45
- loading = false;
46
- return;
47
- }
48
-
49
- try {
50
- const result = await authClient.resetPassword({
51
- newPassword,
52
- token
53
- });
54
-
55
- if (result.error) {
56
- error = result.error.message || 'Failed to reset password';
57
- } else {
58
- success = true;
59
- setTimeout(() => {
60
- goto(resolve('/login'));
61
- }, 2000);
62
- }
63
- } catch (err) {
64
- error = err instanceof Error ? err.message : 'An error occurred';
65
- } finally {
66
- loading = false;
67
- }
68
- }
69
- </script>
70
-
71
- <svelte:head>
72
- <title>Aphex CMS - Reset Password</title>
73
- <meta name="description" content="Reset your Aphex CMS account password securely." />
74
- </svelte:head>
75
-
76
- <div class="bg-muted/40 flex min-h-screen items-center justify-center px-4 py-12">
77
- <div class="w-full max-w-md">
78
- <Card.Root class="shadow-lg">
79
- <Card.Header class="space-y-1">
80
- <Card.Title class="text-center text-2xl font-bold">
81
- {success ? 'Password Reset!' : 'Reset Your Password'}
82
- </Card.Title>
83
- <Card.Description class="text-center">
84
- {success ? 'Redirecting to login...' : 'Enter your new password'}
85
- </Card.Description>
86
- </Card.Header>
87
-
88
- <Card.Content>
89
- {#if success}
90
- <div class="rounded-lg border border-green-500/50 bg-green-500/10 p-4 text-center">
91
- <p class="font-medium text-green-700 dark:text-green-400">
92
- Your password has been reset successfully!
93
- </p>
94
- </div>
95
- {:else}
96
- <form onsubmit={handleSubmit} class="space-y-4">
97
- <!-- Error Alert -->
98
- {#if error}
99
- <div class="border-destructive/50 bg-destructive/10 rounded-lg border p-3">
100
- <p class="text-destructive text-sm font-medium">{error}</p>
101
- </div>
102
- {/if}
103
-
104
- <!-- New Password Field -->
105
- <div class="space-y-2">
106
- <Label for="newPassword">New Password</Label>
107
- <Input
108
- id="newPassword"
109
- type="password"
110
- placeholder="••••••••"
111
- bind:value={newPassword}
112
- required
113
- autocomplete="new-password"
114
- disabled={!token || loading}
115
- />
116
- <p class="text-muted-foreground text-xs">Must be at least 8 characters long</p>
117
- </div>
118
-
119
- <!-- Confirm Password Field -->
120
- <div class="space-y-2">
121
- <Label for="confirmPassword">Confirm Password</Label>
122
- <Input
123
- id="confirmPassword"
124
- type="password"
125
- placeholder="••••••••"
126
- bind:value={confirmPassword}
127
- required
128
- autocomplete="new-password"
129
- disabled={!token || loading}
130
- />
131
- </div>
132
-
133
- <!-- Submit Button -->
134
- <Button type="submit" class="w-full" disabled={!token || loading}>
135
- {#if loading}
136
- <svg
137
- class="mr-2 h-4 w-4 animate-spin"
138
- xmlns="http://www.w3.org/2000/svg"
139
- fill="none"
140
- viewBox="0 0 24 24"
141
- >
142
- <circle
143
- class="opacity-25"
144
- cx="12"
145
- cy="12"
146
- r="10"
147
- stroke="currentColor"
148
- stroke-width="4"
149
- ></circle>
150
- <path
151
- class="opacity-75"
152
- fill="currentColor"
153
- d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
154
- ></path>
155
- </svg>
156
- {/if}
157
- Reset Password
158
- </Button>
159
-
160
- <!-- Back to Login -->
161
- <Button
162
- type="button"
163
- variant="ghost"
164
- class="w-full"
165
- onclick={() => goto(resolve('/login'))}
166
- >
167
- ← Back to Login
168
- </Button>
169
- </form>
170
- {/if}
171
- </Card.Content>
172
- </Card.Root>
173
-
174
- <!-- Footer -->
175
- <p class="text-muted-foreground mt-6 text-center text-xs">
176
- Aphex CMS - Built with SvelteKit & Better Auth
177
- </p>
178
- </div>
179
- </div>
@@ -1,41 +0,0 @@
1
- <script lang="ts">
2
- import { goto } from '$app/navigation';
3
- import { page } from '$app/state';
4
- import { Button } from '@aphexcms/ui/shadcn/button';
5
- import * as Card from '@aphexcms/ui/shadcn/card';
6
-
7
- // Better Auth redirects here after successful verification
8
- // with autoSignInAfterVerification, user may already be signed in
9
- let callbackUrl = $derived(page.url.searchParams.get('callbackUrl'));
10
- </script>
11
-
12
- <svelte:head>
13
- <title>Aphex CMS - Email Verified</title>
14
- </svelte:head>
15
-
16
- <div class="bg-muted/40 flex min-h-screen items-center justify-center px-4 py-12">
17
- <div class="w-full max-w-md">
18
- <Card.Root class="shadow-lg">
19
- <Card.Header class="space-y-1">
20
- <Card.Title class="text-center text-2xl font-bold">Email Verified</Card.Title>
21
- <Card.Description class="text-center">
22
- Your email has been verified successfully
23
- </Card.Description>
24
- </Card.Header>
25
-
26
- <Card.Content>
27
- <div class="rounded-lg border border-green-500/50 bg-green-500/10 p-4 text-center">
28
- <p class="font-medium text-green-700 dark:text-green-400">
29
- Your email address has been verified. You can now sign in.
30
- </p>
31
- </div>
32
-
33
- <Button class="mt-6 w-full" onclick={() => goto(callbackUrl || '/login')}>
34
- Continue to Sign In
35
- </Button>
36
- </Card.Content>
37
- </Card.Root>
38
-
39
- <p class="text-muted-foreground mt-6 text-center text-xs">Aphex CMS - Built with SvelteKit</p>
40
- </div>
41
- </div>
@@ -1,3 +0,0 @@
1
- # allow crawling everything by default
2
- User-agent: *
3
- Disallow:
@@ -1,19 +0,0 @@
1
- import { mdsvex } from 'mdsvex';
2
- import adapterAuto from '@sveltejs/adapter-auto';
3
- import adapterNode from '@sveltejs/adapter-node';
4
- import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
5
-
6
- /** @type {import('@sveltejs/kit').Config} */
7
- const config = {
8
- preprocess: [vitePreprocess(), mdsvex()],
9
- kit: {
10
- adapter: process.env.ADAPTER === 'node' ? adapterNode() : adapterAuto(),
11
- alias: {
12
- '@lib': '../../packages/ui/src/lib',
13
- '@lib/*': '../../packages/ui/src/lib/*'
14
- }
15
- },
16
- extensions: ['.svelte', '.svx']
17
- };
18
-
19
- export default config;
@@ -1,20 +0,0 @@
1
- {
2
- "extends": "./.svelte-kit/tsconfig.json",
3
- "compilerOptions": {
4
- "allowJs": true,
5
- "checkJs": true,
6
- "esModuleInterop": true,
7
- "forceConsistentCasingInFileNames": true,
8
- "resolveJsonModule": true,
9
- "skipLibCheck": true,
10
- "sourceMap": true,
11
- "strict": true,
12
- "moduleResolution": "bundler",
13
- "allowImportingTsExtensions": true
14
- }
15
- // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
16
- // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
17
- //
18
- // To make changes to top-level options such as include and exclude, we recommend extending
19
- // the generated config; see https://svelte.dev/docs/kit/configuration#typescript
20
- }