Skip to content

Commit 2daebaa

Browse files
authored
Merge pull request #1 from Zenfulcode/api-client-integration
Api client integration
2 parents 205fb06 + f5999ce commit 2daebaa

52 files changed

Lines changed: 2178 additions & 3923 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/release.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Build and Publish Docker Image
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
env:
8+
REGISTRY: ghcr.io
9+
IMAGE_NAME: ${{ github.repository }}
10+
11+
jobs:
12+
build-and-push:
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: read
16+
packages: write
17+
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Docker Buildx
23+
uses: docker/setup-buildx-action@v3
24+
25+
- name: Log in to Container Registry
26+
uses: docker/login-action@v3
27+
with:
28+
registry: ${{ env.REGISTRY }}
29+
username: ${{ github.repository_owner }}
30+
password: ${{ secrets.GHCR_TOKEN }}
31+
32+
- name: Convert repository name to lowercase
33+
run: |
34+
echo "IMAGE_NAME_LOWER=${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV
35+
36+
- name: xtract metadata (tags, labels) for Docker
37+
id: meta
38+
uses: docker/metadata-action@v5
39+
with:
40+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LOWER }}
41+
tags: |
42+
type=ref,event=tag
43+
type=semver,pattern={{version}}
44+
type=semver,pattern={{major}}.{{minor}}
45+
type=semver,pattern={{major}}
46+
type=raw,value=latest,enable={{is_default_branch}}
47+
48+
- name: Build and push Docker image
49+
uses: docker/build-push-action@v6
50+
with:
51+
context: .
52+
push: true
53+
tags: ${{ steps.meta.outputs.tags }}
54+
labels: ${{ steps.meta.outputs.labels }}
55+
cache-from: type=gha
56+
cache-to: type=gha,mode=max
57+
platforms: linux/amd64,linux/arm64

Dockerfile.dev

Lines changed: 0 additions & 23 deletions
This file was deleted.

bun.lock

Lines changed: 9 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docker-compose.yml

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -108,29 +108,6 @@ services:
108108
networks:
109109
- commercify-network
110110

111-
# Development service (optional)
112-
commercify-dev:
113-
build:
114-
context: .
115-
dockerfile: Dockerfile.dev
116-
ports:
117-
- '5173:5173'
118-
volumes:
119-
- .:/app
120-
- /app/node_modules
121-
environment:
122-
- NODE_ENV=development
123-
- ORIGIN=http://localhost:5173
124-
- API_BASE_URL_DEV=http://commercify-api:6091/api
125-
- API_BASE_URL_PROD=http://commercify-api:6091/api
126-
depends_on:
127-
- commercify-api
128-
command: bun run dev --host
129-
profiles:
130-
- dev
131-
networks:
132-
- commercify-network
133-
134111
volumes:
135112
postgres_data:
136113

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
"@internationalized/date": "^3.8.2",
1818
"@lucide/svelte": "^0.515.0",
1919
"@sveltejs/adapter-auto": "^6.0.1",
20-
"@sveltejs/adapter-node": "^5.2.12",
21-
"@sveltejs/kit": "^2.22.2",
20+
"@sveltejs/adapter-node": "^5.2.13",
21+
"@sveltejs/kit": "^2.22.5",
2222
"@sveltejs/vite-plugin-svelte": "^5.1.0",
2323
"@tailwindcss/typography": "^0.5.16",
2424
"@tailwindcss/vite": "^4.1.11",
@@ -28,7 +28,7 @@
2828
"mode-watcher": "^1.1.0",
2929
"prettier": "^3.6.2",
3030
"prettier-plugin-svelte": "^3.4.0",
31-
"svelte": "^5.35.2",
31+
"svelte": "^5.35.5",
3232
"svelte-check": "^4.2.2",
3333
"svelte-sonner": "^1.0.5",
3434
"sveltekit-superforms": "^2.27.1",
@@ -40,6 +40,7 @@
4040
"vite": "^6.3.5"
4141
},
4242
"dependencies": {
43+
"commercify-api-client": "^1.2.11",
4344
"lucide-svelte": "^0.515.0",
4445
"zod": "3.25.67"
4546
}

src/app.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ declare global {
77
namespace App {
88
// interface Error {}
99
interface Locals {
10-
commercify: CommercifyClient;
10+
commercify: CachedCommercifyApiClient;
1111
user?: {
1212
email?: string;
1313
name?: string;
1414
role: 'admin';
15-
accessToken: string;
15+
// accessToken: string;
1616
};
1717
}
1818
// interface PageData {}

src/hooks.server.ts

Lines changed: 23 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,51 @@
11
import type { Handle } from '@sveltejs/kit';
2-
import { createCommercifyClient } from '$lib/server/api';
32
import { sequence } from '@sveltejs/kit/hooks';
4-
import { env } from '$env/dynamic/private';
53
import { redirect } from '@sveltejs/kit';
4+
import { CachedCommercifyApiClient, createApiClient } from '$lib/server/commercify/api';
65

76
const handleAuth: Handle = async ({ event, resolve }) => {
87
// Check if the route requires admin authentication
98
if (event.url.pathname.startsWith('/admin')) {
10-
const accessToken = event.cookies.get('access_token');
9+
const { commercify } = event.locals;
1110

12-
// If no access token, redirect to login immediately
13-
if (!accessToken) {
11+
if (!commercify.client.authToken) {
12+
console.log('No auth token found, redirecting to login');
13+
// Redirect to login if no auth token is present
1414
throw redirect(303, '/login');
1515
}
1616

17-
// Create commercify client to validate the token
18-
const cookieString = event.cookies
19-
.getAll()
20-
.map((cookie) => `${cookie.name}=${cookie.value}`)
21-
.join('; ');
22-
23-
const commercifyClient = createCommercifyClient(cookieString);
24-
25-
// Validate the access token by calling getUser()
26-
const userResponse = await commercifyClient.getUser();
27-
28-
if (!userResponse.success || !userResponse.data) {
29-
console.log('Access token validation failed:', userResponse.error);
30-
31-
// Clear all auth-related cookies since token is invalid
32-
event.cookies.delete('access_token', { path: '/' });
17+
try {
18+
const userResponse = await commercify.auth.getUser();
19+
20+
// Add validated user info to locals for use in admin pages
21+
event.locals.user = {
22+
email: userResponse.email,
23+
name: `${userResponse.firstName} ${userResponse.lastName}`,
24+
role: userResponse.role as 'admin'
25+
};
26+
} catch (error) {
27+
event.cookies.delete('auth_token', { path: '/' });
3328
event.cookies.delete('user_role', { path: '/' });
34-
35-
throw redirect(303, '/login');
3629
}
3730

3831
// Verify user has admin role (from validated user data)
39-
if (userResponse.data.role !== 'admin') {
40-
console.log('User does not have admin role:', userResponse.data.role);
32+
if (event.locals.user?.role !== 'admin') {
33+
console.log('User does not have admin role:', event.locals.user!.role);
4134
throw redirect(303, '/login');
4235
}
43-
44-
// Add validated user info to locals for use in admin pages
45-
event.locals.user = {
46-
email: userResponse.data.email,
47-
name: `${userResponse.data.firstName} ${userResponse.data.lastName}`,
48-
role: userResponse.data.role as 'admin',
49-
accessToken
50-
};
5136
}
5237

5338
return resolve(event);
5439
};
5540

5641
const handleCommercify: Handle = async ({ event, resolve }) => {
57-
// Create commercify client with forwarded cookies and store in locals
58-
const cookieString = event.cookies
59-
.getAll()
60-
.map((cookie) => `${cookie.name}=${cookie.value}`)
61-
.join('; ');
62-
63-
event.locals.commercify = createCommercifyClient(cookieString);
64-
65-
// For shop routes, ensure we have a checkout session and set the cookie
66-
if (event.url.pathname.startsWith('/shop')) {
67-
try {
68-
const checkoutResponse = await event.locals.commercify.getOrCreateCheckout('DKK');
42+
// Get the auth token from a secure, httpOnly cookie
43+
const authToken = event.cookies.get('auth_token');
6944

70-
if (checkoutResponse.success && checkoutResponse.data?.id) {
71-
// Set the checkout session cookie
72-
event.cookies.set('checkout_session_id', checkoutResponse.data.id, {
73-
path: '/',
74-
// httpOnly: true,
75-
secure: env.NODE_ENV === 'production', // Set to true in production
76-
// sameSite: 'lax',
77-
maxAge: 86400 * 7 // 7 days
78-
});
79-
}
80-
} catch (error) {
81-
console.error('Error setting up checkout session in hooks:', error);
82-
// Don't fail the request, just log the error
83-
}
84-
}
45+
// Create an API client instance and attach it to the event object
46+
event.locals.commercify = createApiClient(event, authToken) as CachedCommercifyApiClient;
8547

8648
return resolve(event);
8749
};
8850

89-
export const handle: Handle = sequence(handleAuth, handleCommercify);
51+
export const handle: Handle = sequence(handleCommercify, handleAuth);

0 commit comments

Comments
 (0)