@digilogiclabs/create-saas-app 2.7.0 → 2.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/generators/template-generator.d.ts.map +1 -1
- package/dist/generators/template-generator.js +18 -12
- package/dist/generators/template-generator.js.map +1 -1
- package/dist/templates/shared/auth/firebase/web/src/lib/auth-session.ts +25 -0
- package/dist/templates/shared/auth/keycloak/web/src/lib/auth-session.ts +24 -0
- package/dist/templates/shared/auth/supabase/web/src/lib/auth-session.ts +37 -0
- package/dist/templates/shared/config/web/next.config.mjs +1 -0
- package/dist/templates/shared/contact/web/{app → src/app}/api/contact/route.ts +4 -4
- package/{src/templates/shared/database/supabase/web → dist/templates/shared/database/supabase/web/src}/lib/supabase/server.ts +1 -1
- package/dist/templates/shared/loading/web/src/app/loading.tsx +9 -0
- package/dist/templates/shared/payments/web/{app → src/app}/api/webhooks/stripe/route.ts +1 -1
- package/{src/templates/shared/security/web → dist/templates/shared/security/web/src}/lib/api-security.ts +7 -3
- package/dist/templates/web/ai-platform/template/middleware.ts +55 -55
- package/dist/templates/web/ai-platform/template/src/lib/supabase/server.ts +27 -27
- package/dist/templates/web/iot-dashboard/template/middleware.ts +56 -56
- package/dist/templates/web/iot-dashboard/template/src/lib/supabase/server.ts +27 -27
- package/dist/templates/web/marketplace/template/middleware.ts +56 -56
- package/dist/templates/web/marketplace/template/src/lib/supabase/server.ts +27 -27
- package/dist/templates/web/micro-saas/template/middleware.ts +1 -1
- package/dist/templates/web/micro-saas/template/src/lib/supabase/server.ts +29 -29
- package/dist/templates/web/ui-auth-ai/template/package.json +1 -3
- package/dist/templates/web/ui-auth-ai/template/src/app/error.tsx +75 -0
- package/dist/templates/web/ui-auth-ai/template/src/app/loading.tsx +39 -0
- package/dist/templates/web/ui-auth-payments/template/src/components/providers/app-providers.tsx +4 -7
- package/package.json +1 -1
- package/src/templates/shared/auth/firebase/web/src/lib/auth-session.ts +25 -0
- package/src/templates/shared/auth/keycloak/web/src/lib/auth-session.ts +24 -0
- package/src/templates/shared/auth/supabase/web/src/lib/auth-session.ts +37 -0
- package/src/templates/shared/config/web/next.config.mjs +1 -0
- package/src/templates/shared/contact/web/{app → src/app}/api/contact/route.ts +4 -4
- package/{dist/templates/shared/database/supabase/web → src/templates/shared/database/supabase/web/src}/lib/supabase/server.ts +1 -1
- package/src/templates/shared/loading/web/src/app/loading.tsx +9 -0
- package/src/templates/shared/payments/web/{app → src/app}/api/webhooks/stripe/route.ts +1 -1
- package/{dist/templates/shared/security/web → src/templates/shared/security/web/src}/lib/api-security.ts +7 -3
- package/src/templates/web/ai-platform/template/middleware.ts +55 -55
- package/src/templates/web/ai-platform/template/src/lib/supabase/server.ts +27 -27
- package/src/templates/web/iot-dashboard/template/middleware.ts +56 -56
- package/src/templates/web/iot-dashboard/template/src/lib/supabase/server.ts +27 -27
- package/src/templates/web/marketplace/template/middleware.ts +56 -56
- package/src/templates/web/marketplace/template/src/lib/supabase/server.ts +27 -27
- package/src/templates/web/micro-saas/template/middleware.ts +1 -1
- package/src/templates/web/micro-saas/template/src/lib/supabase/server.ts +29 -29
- package/src/templates/web/ui-auth-ai/template/package.json +1 -3
- package/src/templates/web/ui-auth-ai/template/src/app/error.tsx +75 -0
- package/src/templates/web/ui-auth-ai/template/src/app/loading.tsx +39 -0
- package/src/templates/web/ui-auth-payments/template/src/components/providers/app-providers.tsx +4 -7
- package/dist/templates/shared/loading/web/app/loading.tsx +0 -5
- package/dist/templates/web/base/template.backup/.env.example +0 -15
- package/dist/templates/web/ui-auth/template.backup/.env.example +0 -15
- package/dist/templates/web/ui-auth-payments-ai/template/src/app/page.tsx.backup +0 -391
- package/dist/templates/web/ui-auth-payments-ai/template/src/app/page.tsx.bak +0 -391
- package/dist/templates/web/ui-auth-payments-audio/template/src/app/page.tsx.backup +0 -391
- package/dist/templates/web/ui-auth-payments-audio/template/src/app/page.tsx.bak +0 -391
- package/dist/templates/web/ui-only/template.backup/.env.example +0 -15
- package/src/templates/shared/loading/web/app/loading.tsx +0 -5
- /package/dist/templates/shared/admin/web/{app → src/app}/admin/layout.tsx +0 -0
- /package/dist/templates/shared/audit/web/{lib → src/lib}/audit.ts +0 -0
- /package/dist/templates/shared/auth/keycloak/web/{app → src/app}/api/auth/federated-logout/route.ts +0 -0
- /package/dist/templates/shared/beta/web/{app → src/app}/api/beta-settings/route.ts +0 -0
- /package/dist/templates/shared/beta/web/{app → src/app}/api/validate-beta-code/route.ts +0 -0
- /package/dist/templates/shared/beta/web/{lib → src/lib}/beta/settings.ts +0 -0
- /package/dist/templates/shared/cache/web/{lib → src/lib}/cache.ts +0 -0
- /package/dist/templates/shared/config/web/{lib → src/lib}/config.ts +0 -0
- /package/dist/templates/shared/contact/web/{app → src/app}/contact/page.tsx +0 -0
- /package/dist/templates/shared/database/postgresql/web/{lib → src/lib}/db/drizzle.ts +0 -0
- /package/dist/templates/shared/database/postgresql/web/{lib → src/lib}/db/schema.ts +0 -0
- /package/dist/templates/shared/database/supabase/web/{lib → src/lib}/supabase/client.ts +0 -0
- /package/dist/templates/shared/database/supabase/web/{lib → src/lib}/supabase/service.ts +0 -0
- /package/dist/templates/shared/email/web/{lib → src/lib}/email/branding.ts +0 -0
- /package/dist/templates/shared/email/web/{lib → src/lib}/email/client.ts +0 -0
- /package/dist/templates/shared/error-pages/web/{app → src/app}/error.tsx +0 -0
- /package/dist/templates/shared/error-pages/web/{app → src/app}/global-error.tsx +0 -0
- /package/dist/templates/shared/error-pages/web/{app → src/app}/not-found.tsx +0 -0
- /package/dist/templates/shared/health/web/{app → src/app}/api/health/route.ts +0 -0
- /package/dist/templates/shared/legal/web/{app → src/app}/(legal)/privacy/page.tsx +0 -0
- /package/dist/templates/shared/legal/web/{app → src/app}/(legal)/terms/page.tsx +0 -0
- /package/dist/templates/shared/legal/web/{lib → src/lib}/legal-config.ts +0 -0
- /package/dist/templates/shared/observability/web/{lib → src/lib}/observability.ts +0 -0
- /package/dist/templates/shared/platform/web/{lib → src/lib}/platform.ts +0 -0
- /package/dist/templates/shared/redis/web/{lib → src/lib}/rate-limit-store.ts +0 -0
- /package/dist/templates/shared/redis/web/{lib → src/lib}/redis.ts +0 -0
- /package/dist/templates/shared/seo/web/{app → src/app}/api/og/route.tsx +0 -0
- /package/dist/templates/shared/seo/web/{app → src/app}/robots.ts +0 -0
- /package/dist/templates/shared/seo/web/{app → src/app}/sitemap.ts +0 -0
- /package/dist/templates/shared/utils/web/{lib → src/lib}/api-response.ts +0 -0
- /package/dist/templates/shared/utils/web/{lib → src/lib}/utils.ts +0 -0
- /package/src/templates/shared/admin/web/{app → src/app}/admin/layout.tsx +0 -0
- /package/src/templates/shared/audit/web/{lib → src/lib}/audit.ts +0 -0
- /package/src/templates/shared/auth/keycloak/web/{app → src/app}/api/auth/federated-logout/route.ts +0 -0
- /package/src/templates/shared/beta/web/{app → src/app}/api/beta-settings/route.ts +0 -0
- /package/src/templates/shared/beta/web/{app → src/app}/api/validate-beta-code/route.ts +0 -0
- /package/src/templates/shared/beta/web/{lib → src/lib}/beta/settings.ts +0 -0
- /package/src/templates/shared/cache/web/{lib → src/lib}/cache.ts +0 -0
- /package/src/templates/shared/config/web/{lib → src/lib}/config.ts +0 -0
- /package/src/templates/shared/contact/web/{app → src/app}/contact/page.tsx +0 -0
- /package/src/templates/shared/database/postgresql/web/{lib → src/lib}/db/drizzle.ts +0 -0
- /package/src/templates/shared/database/postgresql/web/{lib → src/lib}/db/schema.ts +0 -0
- /package/src/templates/shared/database/supabase/web/{lib → src/lib}/supabase/client.ts +0 -0
- /package/src/templates/shared/database/supabase/web/{lib → src/lib}/supabase/service.ts +0 -0
- /package/src/templates/shared/email/web/{lib → src/lib}/email/branding.ts +0 -0
- /package/src/templates/shared/email/web/{lib → src/lib}/email/client.ts +0 -0
- /package/src/templates/shared/error-pages/web/{app → src/app}/error.tsx +0 -0
- /package/src/templates/shared/error-pages/web/{app → src/app}/global-error.tsx +0 -0
- /package/src/templates/shared/error-pages/web/{app → src/app}/not-found.tsx +0 -0
- /package/src/templates/shared/health/web/{app → src/app}/api/health/route.ts +0 -0
- /package/src/templates/shared/legal/web/{app → src/app}/(legal)/privacy/page.tsx +0 -0
- /package/src/templates/shared/legal/web/{app → src/app}/(legal)/terms/page.tsx +0 -0
- /package/src/templates/shared/legal/web/{lib → src/lib}/legal-config.ts +0 -0
- /package/src/templates/shared/observability/web/{lib → src/lib}/observability.ts +0 -0
- /package/src/templates/shared/platform/web/{lib → src/lib}/platform.ts +0 -0
- /package/src/templates/shared/redis/web/{lib → src/lib}/rate-limit-store.ts +0 -0
- /package/src/templates/shared/redis/web/{lib → src/lib}/redis.ts +0 -0
- /package/src/templates/shared/seo/web/{app → src/app}/api/og/route.tsx +0 -0
- /package/src/templates/shared/seo/web/{app → src/app}/robots.ts +0 -0
- /package/src/templates/shared/seo/web/{app → src/app}/sitemap.ts +0 -0
- /package/src/templates/shared/utils/web/{lib → src/lib}/api-response.ts +0 -0
- /package/src/templates/shared/utils/web/{lib → src/lib}/utils.ts +0 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* POST — Submit a contact form message.
|
|
5
5
|
* Public endpoint with rate limiting. Sends email via Resend.
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import { NextResponse } from 'next/server';
|
|
8
8
|
import { z } from 'zod';
|
|
9
9
|
import { withPublicApi, escapeHtml } from '@/lib/api-security';
|
|
10
10
|
import { sendEmail } from '@/lib/email/client';
|
|
@@ -23,7 +23,7 @@ const ContactSchema = z.object({
|
|
|
23
23
|
name: z.string().min(2, 'Name must be at least 2 characters').max(100, 'Name is too long'),
|
|
24
24
|
email: z.string().email('Please enter a valid email address').max(255),
|
|
25
25
|
category: z.enum(['general', 'support', 'business', 'feedback', 'other'], {
|
|
26
|
-
|
|
26
|
+
error: 'Please select a category',
|
|
27
27
|
}),
|
|
28
28
|
message: z
|
|
29
29
|
.string()
|
|
@@ -39,9 +39,9 @@ const ContactSchema = z.object({
|
|
|
39
39
|
export const POST = withPublicApi(
|
|
40
40
|
{
|
|
41
41
|
operation: 'contact/post',
|
|
42
|
-
rateLimit:
|
|
42
|
+
rateLimit: 'publicRead',
|
|
43
43
|
},
|
|
44
|
-
async (request
|
|
44
|
+
async (request) => {
|
|
45
45
|
const body = await request.json();
|
|
46
46
|
const parsed = ContactSchema.safeParse(body);
|
|
47
47
|
|
|
@@ -16,7 +16,7 @@ export async function createClient() {
|
|
|
16
16
|
getAll() {
|
|
17
17
|
return cookieStore.getAll();
|
|
18
18
|
},
|
|
19
|
-
setAll(cookiesToSet) {
|
|
19
|
+
setAll(cookiesToSet: Array<{ name: string; value: string; options?: Record<string, unknown> }>) {
|
|
20
20
|
try {
|
|
21
21
|
cookiesToSet.forEach(({ name, value, options }) =>
|
|
22
22
|
cookieStore.set(name, value, options)
|
|
@@ -16,7 +16,7 @@ import { enforceRateLimit, AppRateLimits } from '@/lib/api-security';
|
|
|
16
16
|
export const dynamic = 'force-dynamic';
|
|
17
17
|
|
|
18
18
|
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
|
|
19
|
-
apiVersion: '
|
|
19
|
+
apiVersion: '2025-02-24.acacia',
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
/**
|
|
@@ -114,10 +114,14 @@ export const {
|
|
|
114
114
|
AppRateLimitPreset
|
|
115
115
|
>({
|
|
116
116
|
getSession: async () => {
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
// Import the auth session adapter — see @/lib/auth-session.ts
|
|
118
|
+
const { getSession } = await import('@/lib/auth-session');
|
|
119
|
+
return getSession();
|
|
120
|
+
},
|
|
121
|
+
isAdmin: (session) => {
|
|
122
|
+
const roles = (session?.user as Record<string, unknown>)?.roles;
|
|
123
|
+
return Array.isArray(roles) && roles.includes('admin');
|
|
119
124
|
},
|
|
120
|
-
isAdmin: (session) => session?.user?.roles?.includes('admin') ?? false,
|
|
121
125
|
rateLimiter: {
|
|
122
126
|
enforce: enforcePreset,
|
|
123
127
|
publicDefault: 'publicRead',
|
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
import { createServerClient } from '@supabase/ssr'
|
|
2
|
-
import { NextResponse, type NextRequest } from 'next/server'
|
|
3
|
-
|
|
4
|
-
export async function middleware(request: NextRequest) {
|
|
5
|
-
let supabaseResponse = NextResponse.next({
|
|
6
|
-
request,
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
const supabase = createServerClient(
|
|
10
|
-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
11
|
-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
12
|
-
{
|
|
13
|
-
cookies: {
|
|
14
|
-
getAll() {
|
|
15
|
-
return request.cookies.getAll()
|
|
16
|
-
},
|
|
17
|
-
setAll(cookiesToSet) {
|
|
18
|
-
cookiesToSet.forEach(({ name, value }) =>
|
|
19
|
-
request.cookies.set(name, value)
|
|
20
|
-
)
|
|
21
|
-
supabaseResponse = NextResponse.next({
|
|
22
|
-
request,
|
|
23
|
-
})
|
|
24
|
-
cookiesToSet.forEach(({ name, value, options }) =>
|
|
25
|
-
supabaseResponse.cookies.set(name, value, options)
|
|
26
|
-
)
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
}
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
const {
|
|
33
|
-
data: { user },
|
|
34
|
-
} = await supabase.auth.getUser()
|
|
35
|
-
|
|
36
|
-
// Redirect to login if accessing protected route without auth
|
|
37
|
-
if (
|
|
38
|
-
!user &&
|
|
39
|
-
(request.nextUrl.pathname.startsWith('/dashboard') ||
|
|
40
|
-
request.nextUrl.pathname.startsWith('/chat') ||
|
|
41
|
-
request.nextUrl.pathname.startsWith('/playground'))
|
|
42
|
-
) {
|
|
43
|
-
const url = request.nextUrl.clone()
|
|
44
|
-
url.pathname = '/login'
|
|
45
|
-
return NextResponse.redirect(url)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return supabaseResponse
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export const config = {
|
|
52
|
-
matcher: [
|
|
53
|
-
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
|
|
54
|
-
],
|
|
55
|
-
}
|
|
1
|
+
import { createServerClient } from '@supabase/ssr'
|
|
2
|
+
import { NextResponse, type NextRequest } from 'next/server'
|
|
3
|
+
|
|
4
|
+
export async function middleware(request: NextRequest) {
|
|
5
|
+
let supabaseResponse = NextResponse.next({
|
|
6
|
+
request,
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
const supabase = createServerClient(
|
|
10
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
11
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
12
|
+
{
|
|
13
|
+
cookies: {
|
|
14
|
+
getAll() {
|
|
15
|
+
return request.cookies.getAll()
|
|
16
|
+
},
|
|
17
|
+
setAll(cookiesToSet: Array<{ name: string; value: string; options?: Record<string, unknown> }>) {
|
|
18
|
+
cookiesToSet.forEach(({ name, value }) =>
|
|
19
|
+
request.cookies.set(name, value)
|
|
20
|
+
)
|
|
21
|
+
supabaseResponse = NextResponse.next({
|
|
22
|
+
request,
|
|
23
|
+
})
|
|
24
|
+
cookiesToSet.forEach(({ name, value, options }) =>
|
|
25
|
+
supabaseResponse.cookies.set(name, value, options)
|
|
26
|
+
)
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
const {
|
|
33
|
+
data: { user },
|
|
34
|
+
} = await supabase.auth.getUser()
|
|
35
|
+
|
|
36
|
+
// Redirect to login if accessing protected route without auth
|
|
37
|
+
if (
|
|
38
|
+
!user &&
|
|
39
|
+
(request.nextUrl.pathname.startsWith('/dashboard') ||
|
|
40
|
+
request.nextUrl.pathname.startsWith('/chat') ||
|
|
41
|
+
request.nextUrl.pathname.startsWith('/playground'))
|
|
42
|
+
) {
|
|
43
|
+
const url = request.nextUrl.clone()
|
|
44
|
+
url.pathname = '/login'
|
|
45
|
+
return NextResponse.redirect(url)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return supabaseResponse
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const config = {
|
|
52
|
+
matcher: [
|
|
53
|
+
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
|
|
54
|
+
],
|
|
55
|
+
}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { createServerClient } from '@supabase/ssr'
|
|
2
|
-
import { cookies } from 'next/headers'
|
|
3
|
-
|
|
4
|
-
export async function createClient() {
|
|
5
|
-
const cookieStore = await cookies()
|
|
6
|
-
|
|
7
|
-
return createServerClient(
|
|
8
|
-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
9
|
-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
10
|
-
{
|
|
11
|
-
cookies: {
|
|
12
|
-
getAll() {
|
|
13
|
-
return cookieStore.getAll()
|
|
14
|
-
},
|
|
15
|
-
setAll(cookiesToSet) {
|
|
16
|
-
try {
|
|
17
|
-
cookiesToSet.forEach(({ name, value, options }) =>
|
|
18
|
-
cookieStore.set(name, value, options)
|
|
19
|
-
)
|
|
20
|
-
} catch {
|
|
21
|
-
// Server Component context
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
}
|
|
26
|
-
)
|
|
27
|
-
}
|
|
1
|
+
import { createServerClient } from '@supabase/ssr'
|
|
2
|
+
import { cookies } from 'next/headers'
|
|
3
|
+
|
|
4
|
+
export async function createClient() {
|
|
5
|
+
const cookieStore = await cookies()
|
|
6
|
+
|
|
7
|
+
return createServerClient(
|
|
8
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
9
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
10
|
+
{
|
|
11
|
+
cookies: {
|
|
12
|
+
getAll() {
|
|
13
|
+
return cookieStore.getAll()
|
|
14
|
+
},
|
|
15
|
+
setAll(cookiesToSet: Array<{ name: string; value: string; options?: Record<string, unknown> }>) {
|
|
16
|
+
try {
|
|
17
|
+
cookiesToSet.forEach(({ name, value, options }) =>
|
|
18
|
+
cookieStore.set(name, value, options)
|
|
19
|
+
)
|
|
20
|
+
} catch {
|
|
21
|
+
// Server Component context
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
}
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
import { createServerClient } from '@supabase/ssr'
|
|
2
|
-
import { NextResponse, type NextRequest } from 'next/server'
|
|
3
|
-
|
|
4
|
-
export async function middleware(request: NextRequest) {
|
|
5
|
-
let supabaseResponse = NextResponse.next({
|
|
6
|
-
request,
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
const supabase = createServerClient(
|
|
10
|
-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
11
|
-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
12
|
-
{
|
|
13
|
-
cookies: {
|
|
14
|
-
getAll() {
|
|
15
|
-
return request.cookies.getAll()
|
|
16
|
-
},
|
|
17
|
-
setAll(cookiesToSet) {
|
|
18
|
-
cookiesToSet.forEach(({ name, value }) =>
|
|
19
|
-
request.cookies.set(name, value)
|
|
20
|
-
)
|
|
21
|
-
supabaseResponse = NextResponse.next({
|
|
22
|
-
request,
|
|
23
|
-
})
|
|
24
|
-
cookiesToSet.forEach(({ name, value, options }) =>
|
|
25
|
-
supabaseResponse.cookies.set(name, value, options)
|
|
26
|
-
)
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
}
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
const {
|
|
33
|
-
data: { user },
|
|
34
|
-
} = await supabase.auth.getUser()
|
|
35
|
-
|
|
36
|
-
// Redirect to login if accessing protected route without auth
|
|
37
|
-
if (
|
|
38
|
-
!user &&
|
|
39
|
-
(request.nextUrl.pathname.startsWith('/dashboard') ||
|
|
40
|
-
request.nextUrl.pathname.startsWith('/devices') ||
|
|
41
|
-
request.nextUrl.pathname.startsWith('/analytics') ||
|
|
42
|
-
request.nextUrl.pathname.startsWith('/alerts'))
|
|
43
|
-
) {
|
|
44
|
-
const url = request.nextUrl.clone()
|
|
45
|
-
url.pathname = '/login'
|
|
46
|
-
return NextResponse.redirect(url)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return supabaseResponse
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export const config = {
|
|
53
|
-
matcher: [
|
|
54
|
-
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
|
|
55
|
-
],
|
|
56
|
-
}
|
|
1
|
+
import { createServerClient } from '@supabase/ssr'
|
|
2
|
+
import { NextResponse, type NextRequest } from 'next/server'
|
|
3
|
+
|
|
4
|
+
export async function middleware(request: NextRequest) {
|
|
5
|
+
let supabaseResponse = NextResponse.next({
|
|
6
|
+
request,
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
const supabase = createServerClient(
|
|
10
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
11
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
12
|
+
{
|
|
13
|
+
cookies: {
|
|
14
|
+
getAll() {
|
|
15
|
+
return request.cookies.getAll()
|
|
16
|
+
},
|
|
17
|
+
setAll(cookiesToSet: Array<{ name: string; value: string; options?: Record<string, unknown> }>) {
|
|
18
|
+
cookiesToSet.forEach(({ name, value }) =>
|
|
19
|
+
request.cookies.set(name, value)
|
|
20
|
+
)
|
|
21
|
+
supabaseResponse = NextResponse.next({
|
|
22
|
+
request,
|
|
23
|
+
})
|
|
24
|
+
cookiesToSet.forEach(({ name, value, options }) =>
|
|
25
|
+
supabaseResponse.cookies.set(name, value, options)
|
|
26
|
+
)
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
const {
|
|
33
|
+
data: { user },
|
|
34
|
+
} = await supabase.auth.getUser()
|
|
35
|
+
|
|
36
|
+
// Redirect to login if accessing protected route without auth
|
|
37
|
+
if (
|
|
38
|
+
!user &&
|
|
39
|
+
(request.nextUrl.pathname.startsWith('/dashboard') ||
|
|
40
|
+
request.nextUrl.pathname.startsWith('/devices') ||
|
|
41
|
+
request.nextUrl.pathname.startsWith('/analytics') ||
|
|
42
|
+
request.nextUrl.pathname.startsWith('/alerts'))
|
|
43
|
+
) {
|
|
44
|
+
const url = request.nextUrl.clone()
|
|
45
|
+
url.pathname = '/login'
|
|
46
|
+
return NextResponse.redirect(url)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return supabaseResponse
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const config = {
|
|
53
|
+
matcher: [
|
|
54
|
+
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
|
|
55
|
+
],
|
|
56
|
+
}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { createServerClient } from '@supabase/ssr'
|
|
2
|
-
import { cookies } from 'next/headers'
|
|
3
|
-
|
|
4
|
-
export async function createClient() {
|
|
5
|
-
const cookieStore = await cookies()
|
|
6
|
-
|
|
7
|
-
return createServerClient(
|
|
8
|
-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
9
|
-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
10
|
-
{
|
|
11
|
-
cookies: {
|
|
12
|
-
getAll() {
|
|
13
|
-
return cookieStore.getAll()
|
|
14
|
-
},
|
|
15
|
-
setAll(cookiesToSet) {
|
|
16
|
-
try {
|
|
17
|
-
cookiesToSet.forEach(({ name, value, options }) =>
|
|
18
|
-
cookieStore.set(name, value, options)
|
|
19
|
-
)
|
|
20
|
-
} catch {
|
|
21
|
-
// Server Component context
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
}
|
|
26
|
-
)
|
|
27
|
-
}
|
|
1
|
+
import { createServerClient } from '@supabase/ssr'
|
|
2
|
+
import { cookies } from 'next/headers'
|
|
3
|
+
|
|
4
|
+
export async function createClient() {
|
|
5
|
+
const cookieStore = await cookies()
|
|
6
|
+
|
|
7
|
+
return createServerClient(
|
|
8
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
9
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
10
|
+
{
|
|
11
|
+
cookies: {
|
|
12
|
+
getAll() {
|
|
13
|
+
return cookieStore.getAll()
|
|
14
|
+
},
|
|
15
|
+
setAll(cookiesToSet: Array<{ name: string; value: string; options?: Record<string, unknown> }>) {
|
|
16
|
+
try {
|
|
17
|
+
cookiesToSet.forEach(({ name, value, options }) =>
|
|
18
|
+
cookieStore.set(name, value, options)
|
|
19
|
+
)
|
|
20
|
+
} catch {
|
|
21
|
+
// Server Component context
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
}
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
import { createServerClient } from '@supabase/ssr'
|
|
2
|
-
import { NextResponse, type NextRequest } from 'next/server'
|
|
3
|
-
|
|
4
|
-
export async function middleware(request: NextRequest) {
|
|
5
|
-
let supabaseResponse = NextResponse.next({
|
|
6
|
-
request,
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
const supabase = createServerClient(
|
|
10
|
-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
11
|
-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
12
|
-
{
|
|
13
|
-
cookies: {
|
|
14
|
-
getAll() {
|
|
15
|
-
return request.cookies.getAll()
|
|
16
|
-
},
|
|
17
|
-
setAll(cookiesToSet) {
|
|
18
|
-
cookiesToSet.forEach(({ name, value }) =>
|
|
19
|
-
request.cookies.set(name, value)
|
|
20
|
-
)
|
|
21
|
-
supabaseResponse = NextResponse.next({
|
|
22
|
-
request,
|
|
23
|
-
})
|
|
24
|
-
cookiesToSet.forEach(({ name, value, options }) =>
|
|
25
|
-
supabaseResponse.cookies.set(name, value, options)
|
|
26
|
-
)
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
}
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
const {
|
|
33
|
-
data: { user },
|
|
34
|
-
} = await supabase.auth.getUser()
|
|
35
|
-
|
|
36
|
-
// Redirect to login if accessing protected route without auth
|
|
37
|
-
if (
|
|
38
|
-
!user &&
|
|
39
|
-
(request.nextUrl.pathname.startsWith('/dashboard') ||
|
|
40
|
-
request.nextUrl.pathname.startsWith('/products/new') ||
|
|
41
|
-
request.nextUrl.pathname.startsWith('/orders') ||
|
|
42
|
-
request.nextUrl.pathname.startsWith('/payouts'))
|
|
43
|
-
) {
|
|
44
|
-
const url = request.nextUrl.clone()
|
|
45
|
-
url.pathname = '/login'
|
|
46
|
-
return NextResponse.redirect(url)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return supabaseResponse
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export const config = {
|
|
53
|
-
matcher: [
|
|
54
|
-
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
|
|
55
|
-
],
|
|
56
|
-
}
|
|
1
|
+
import { createServerClient } from '@supabase/ssr'
|
|
2
|
+
import { NextResponse, type NextRequest } from 'next/server'
|
|
3
|
+
|
|
4
|
+
export async function middleware(request: NextRequest) {
|
|
5
|
+
let supabaseResponse = NextResponse.next({
|
|
6
|
+
request,
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
const supabase = createServerClient(
|
|
10
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
11
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
12
|
+
{
|
|
13
|
+
cookies: {
|
|
14
|
+
getAll() {
|
|
15
|
+
return request.cookies.getAll()
|
|
16
|
+
},
|
|
17
|
+
setAll(cookiesToSet: Array<{ name: string; value: string; options?: Record<string, unknown> }>) {
|
|
18
|
+
cookiesToSet.forEach(({ name, value }) =>
|
|
19
|
+
request.cookies.set(name, value)
|
|
20
|
+
)
|
|
21
|
+
supabaseResponse = NextResponse.next({
|
|
22
|
+
request,
|
|
23
|
+
})
|
|
24
|
+
cookiesToSet.forEach(({ name, value, options }) =>
|
|
25
|
+
supabaseResponse.cookies.set(name, value, options)
|
|
26
|
+
)
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
const {
|
|
33
|
+
data: { user },
|
|
34
|
+
} = await supabase.auth.getUser()
|
|
35
|
+
|
|
36
|
+
// Redirect to login if accessing protected route without auth
|
|
37
|
+
if (
|
|
38
|
+
!user &&
|
|
39
|
+
(request.nextUrl.pathname.startsWith('/dashboard') ||
|
|
40
|
+
request.nextUrl.pathname.startsWith('/products/new') ||
|
|
41
|
+
request.nextUrl.pathname.startsWith('/orders') ||
|
|
42
|
+
request.nextUrl.pathname.startsWith('/payouts'))
|
|
43
|
+
) {
|
|
44
|
+
const url = request.nextUrl.clone()
|
|
45
|
+
url.pathname = '/login'
|
|
46
|
+
return NextResponse.redirect(url)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return supabaseResponse
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const config = {
|
|
53
|
+
matcher: [
|
|
54
|
+
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
|
|
55
|
+
],
|
|
56
|
+
}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { createServerClient } from '@supabase/ssr'
|
|
2
|
-
import { cookies } from 'next/headers'
|
|
3
|
-
|
|
4
|
-
export async function createClient() {
|
|
5
|
-
const cookieStore = await cookies()
|
|
6
|
-
|
|
7
|
-
return createServerClient(
|
|
8
|
-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
9
|
-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
10
|
-
{
|
|
11
|
-
cookies: {
|
|
12
|
-
getAll() {
|
|
13
|
-
return cookieStore.getAll()
|
|
14
|
-
},
|
|
15
|
-
setAll(cookiesToSet) {
|
|
16
|
-
try {
|
|
17
|
-
cookiesToSet.forEach(({ name, value, options }) =>
|
|
18
|
-
cookieStore.set(name, value, options)
|
|
19
|
-
)
|
|
20
|
-
} catch {
|
|
21
|
-
// Server Component context
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
}
|
|
26
|
-
)
|
|
27
|
-
}
|
|
1
|
+
import { createServerClient } from '@supabase/ssr'
|
|
2
|
+
import { cookies } from 'next/headers'
|
|
3
|
+
|
|
4
|
+
export async function createClient() {
|
|
5
|
+
const cookieStore = await cookies()
|
|
6
|
+
|
|
7
|
+
return createServerClient(
|
|
8
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
9
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
10
|
+
{
|
|
11
|
+
cookies: {
|
|
12
|
+
getAll() {
|
|
13
|
+
return cookieStore.getAll()
|
|
14
|
+
},
|
|
15
|
+
setAll(cookiesToSet: Array<{ name: string; value: string; options?: Record<string, unknown> }>) {
|
|
16
|
+
try {
|
|
17
|
+
cookiesToSet.forEach(({ name, value, options }) =>
|
|
18
|
+
cookieStore.set(name, value, options)
|
|
19
|
+
)
|
|
20
|
+
} catch {
|
|
21
|
+
// Server Component context
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
}
|
|
@@ -14,7 +14,7 @@ export async function middleware(request: NextRequest) {
|
|
|
14
14
|
getAll() {
|
|
15
15
|
return request.cookies.getAll()
|
|
16
16
|
},
|
|
17
|
-
setAll(cookiesToSet) {
|
|
17
|
+
setAll(cookiesToSet: Array<{ name: string; value: string; options?: Record<string, unknown> }>) {
|
|
18
18
|
cookiesToSet.forEach(({ name, value }) =>
|
|
19
19
|
request.cookies.set(name, value)
|
|
20
20
|
)
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import { createServerClient } from '@supabase/ssr'
|
|
2
|
-
import { cookies } from 'next/headers'
|
|
3
|
-
|
|
4
|
-
export async function createClient() {
|
|
5
|
-
const cookieStore = await cookies()
|
|
6
|
-
|
|
7
|
-
return createServerClient(
|
|
8
|
-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
9
|
-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
10
|
-
{
|
|
11
|
-
cookies: {
|
|
12
|
-
getAll() {
|
|
13
|
-
return cookieStore.getAll()
|
|
14
|
-
},
|
|
15
|
-
setAll(cookiesToSet) {
|
|
16
|
-
try {
|
|
17
|
-
cookiesToSet.forEach(({ name, value, options }) =>
|
|
18
|
-
cookieStore.set(name, value, options)
|
|
19
|
-
)
|
|
20
|
-
} catch {
|
|
21
|
-
// The `setAll` method was called from a Server Component.
|
|
22
|
-
// This can be ignored if you have middleware refreshing
|
|
23
|
-
// user sessions.
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
}
|
|
28
|
-
)
|
|
29
|
-
}
|
|
1
|
+
import { createServerClient } from '@supabase/ssr'
|
|
2
|
+
import { cookies } from 'next/headers'
|
|
3
|
+
|
|
4
|
+
export async function createClient() {
|
|
5
|
+
const cookieStore = await cookies()
|
|
6
|
+
|
|
7
|
+
return createServerClient(
|
|
8
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
9
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
10
|
+
{
|
|
11
|
+
cookies: {
|
|
12
|
+
getAll() {
|
|
13
|
+
return cookieStore.getAll()
|
|
14
|
+
},
|
|
15
|
+
setAll(cookiesToSet: Array<{ name: string; value: string; options?: Record<string, unknown> }>) {
|
|
16
|
+
try {
|
|
17
|
+
cookiesToSet.forEach(({ name, value, options }) =>
|
|
18
|
+
cookieStore.set(name, value, options)
|
|
19
|
+
)
|
|
20
|
+
} catch {
|
|
21
|
+
// The `setAll` method was called from a Server Component.
|
|
22
|
+
// This can be ignored if you have middleware refreshing
|
|
23
|
+
// user sessions.
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
)
|
|
29
|
+
}
|
|
@@ -18,9 +18,7 @@
|
|
|
18
18
|
"clsx": "^2.0.0",
|
|
19
19
|
"tailwindcss": "^3.3.0",
|
|
20
20
|
"autoprefixer": "^10.4.16",
|
|
21
|
-
"postcss": "^8.4.31"
|
|
22
|
-
"@digilogiclabs/saas-factory-ai": "^4.0.2",
|
|
23
|
-
"@digilogiclabs/saas-factory-ai-types": "^4.0.2"{{/ai.enabled}}
|
|
21
|
+
"postcss": "^8.4.31"
|
|
24
22
|
},
|
|
25
23
|
"devDependencies": {
|
|
26
24
|
"@types/node": "^20.0.0",
|