Skip to content

Commit f7a564b

Browse files
committed
include firebase ssr auth
1 parent d0d618e commit f7a564b

File tree

16 files changed

+727
-414
lines changed

16 files changed

+727
-414
lines changed

apps/codingcatdev/package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
"format": "prettier --plugin-search-dir . --write ."
1515
},
1616
"devDependencies": {
17-
"@codingcatdev/blackcatui": "^0.0.4",
17+
"@auth/core": "^0.5.1",
18+
"@auth/sveltekit": "^0.3.0",
19+
"@codingcatdev/blackcatui": "^0.0.5",
1820
"@firebase/app-types": "~0.9.0",
1921
"@playwright/test": "^1.31.1",
2022
"@steeze-ui/heroicons": "^2.2.2",
@@ -23,6 +25,7 @@
2325
"@sveltejs/adapter-auto": "^2.0.0",
2426
"@sveltejs/adapter-vercel": "^2.2.1",
2527
"@sveltejs/kit": "^1.9.3",
28+
"@tailwindcss/forms": "^0.5.3",
2629
"@tailwindcss/typography": "^0.5.9",
2730
"@types/marked": "^4.0.8",
2831
"@types/prismjs": "^1.26.0",
@@ -31,6 +34,7 @@
3134
"eslint": "^8.35.0",
3235
"eslint-config-prettier": "^8.6.0",
3336
"eslint-plugin-svelte3": "^4.0.0",
37+
"firebase-admin": "^11.5.0",
3438
"marked": "^4.2.12",
3539
"postcss": "^8.4.21",
3640
"postcss-load-config": "^4.0.1",
@@ -50,8 +54,7 @@
5054
"@cloudinary/html": "^1.11.0",
5155
"@cloudinary/url-gen": "^1.9.1",
5256
"@codingcatdev/videojs-codingcatdev-youtube": "^0.0.2",
53-
"firebase": "^9.17.1",
54-
"firebase-admin": "^11.5.0",
57+
"firebase": "^9.19.1",
5558
"mdsvex": "^0.10.6",
5659
"prism-svelte": "^0.5.0",
5760
"prism-themes": "^1.9.0",

apps/codingcatdev/src/lib/client/content/content.ts

Lines changed: 0 additions & 85 deletions
This file was deleted.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { initializeApp, getApps } from 'firebase/app';
2+
import { getAuth, setPersistence, browserSessionPersistence, signInWithEmailAndPassword } from 'firebase/auth';
3+
4+
import {
5+
PUBLIC_FB_API_KEY,
6+
PUBLIC_FB_AUTH_DOMAIN,
7+
PUBLIC_FB_PROJECT_ID,
8+
PUBLIC_FB_STORAGE_BUCKET,
9+
PUBLIC_FB_MESSAGE_SENDER_ID,
10+
PUBLIC_FB_APP_ID,
11+
PUBLIC_FB_MEASUREMENT_ID
12+
} from '$env/static/public';
13+
14+
const firebaseConfig = {
15+
apiKey: PUBLIC_FB_API_KEY,
16+
authDomain: PUBLIC_FB_AUTH_DOMAIN,
17+
projectId: PUBLIC_FB_PROJECT_ID,
18+
storageBucket: PUBLIC_FB_STORAGE_BUCKET,
19+
messagingSenderId: PUBLIC_FB_MESSAGE_SENDER_ID,
20+
appId: PUBLIC_FB_APP_ID,
21+
measurementId: PUBLIC_FB_MEASUREMENT_ID
22+
};
23+
24+
export let app = getApps().at(0);
25+
if (!app) {
26+
app = initializeApp(firebaseConfig);
27+
}
28+
export const auth = getAuth(app);
29+
// As httpOnly cookies are to be used, do not persist any state client side.
30+
setPersistence(auth, browserSessionPersistence);
31+
32+
/* AUTH */
33+
34+
export const ccdSignInWithEmailAndPassword = async ({ email, password }: { email: string, password: string }) => {
35+
const userResponse = await signInWithEmailAndPassword(auth, email, password);
36+
const idToken = await userResponse.user.getIdToken();
37+
document.cookie = '__ccdlogin=' + idToken + ';max-age=3600';
38+
}

apps/codingcatdev/src/lib/client/monaco/monaco.js

Lines changed: 0 additions & 45 deletions
This file was deleted.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { initializeApp, getApps, cert } from 'firebase-admin/app';
2+
import { getAuth } from 'firebase-admin/auth';
3+
4+
import {
5+
PUBLIC_FB_PROJECT_ID,
6+
} from '$env/static/public';
7+
8+
import {
9+
PRIVATE_FB_CLIENT_EMAIL,
10+
PRIVATE_FB_PRIVATE_KEY
11+
} from '$env/static/private';
12+
13+
export let app = getApps().at(0);
14+
if (!app) {
15+
app = initializeApp({
16+
credential: cert({
17+
projectId: PUBLIC_FB_PROJECT_ID,
18+
clientEmail: PRIVATE_FB_CLIENT_EMAIL,
19+
privateKey: PRIVATE_FB_PRIVATE_KEY
20+
})
21+
});
22+
}
23+
24+
export const auth = getAuth(app);
25+
26+
export const ccdCreateSessionCookie = async (idToken: string) => {
27+
// Set session expiration to 5 days.
28+
const expiresIn = 60 * 60 * 24 * 5 * 1000;
29+
30+
const sessionCookie = await auth.createSessionCookie(idToken, { expiresIn });
31+
// Set cookie policy for session cookie.
32+
const options = { maxAge: expiresIn, httpOnly: true, secure: true };
33+
34+
return {
35+
name: 'session',
36+
sessionCookie,
37+
options
38+
}
39+
};
40+
41+
export const ccdValidateSessionCookie = async (session: string) => {
42+
return await auth.verifySessionCookie(session, true);
43+
}

apps/codingcatdev/src/routes/(home-partials)/HomeDetail.svelte

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import KCAlt from '$lib/components/global/icons/KCAlt.svelte';
44
import AJHeartAlt from '$lib/components/global/icons/AJHeartAlt.svelte';
55
import Podcasts from '$lib/components/global/icons/nav/Podcasts.svelte';
6-
import BreakBarLeft from '$lib/components/home/BreakBarLeft.svelte';
7-
import BreakBarRight from '$lib/components/home/BreakBarRight.svelte';
8-
import Skills from '$lib/components/home/Skills.svelte';
6+
import BreakBarLeft from './BreakBarLeft.svelte';
7+
import BreakBarRight from './BreakBarRight.svelte';
8+
import Skills from './Skills.svelte';
99
import ContentCards from '$lib/components/content/ContentCards.svelte';
1010
import { ContentType, type Content, type Podcast } from '$lib/types/index';
1111
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { ccdValidateSessionCookie } from '$lib/server/firebase';
2+
import { redirect } from '@sveltejs/kit';
3+
import type { LayoutServerLoad } from './$types';
4+
5+
export const load = (async ({ cookies }) => {
6+
const ccdsession = cookies.get('session');
7+
8+
if (!ccdsession) {
9+
throw redirect(307, '/login');
10+
}
11+
12+
const decodedClaims = await ccdValidateSessionCookie(ccdsession);
13+
14+
if (!decodedClaims) {
15+
throw redirect(307, '/login');
16+
}
17+
18+
return {
19+
user: decodedClaims
20+
};
21+
}) satisfies LayoutServerLoad;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script lang="ts">
2+
import LayoutWrapper from '../../(layout-partials)/LayoutWrapper.svelte';
3+
import type { PageData } from './$types';
4+
5+
export let data: PageData;
6+
</script>
7+
8+
<LayoutWrapper>
9+
<h1>{data.user?.email}</h1>
10+
</LayoutWrapper>
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import { listContent } from '$lib/server/content';
2-
import { ContentType } from '$lib/types';
1+
import { ccdValidateSessionCookie } from '$lib/server/firebase';
32
import type { LayoutServerLoad } from './$types';
43

5-
export const load = (async () => {
4+
export const load = (async ({ cookies }) => {
5+
const ccdsession = cookies.get('session');
6+
if (!ccdsession) {
7+
return {};
8+
}
9+
const decodedClaims = await ccdValidateSessionCookie(ccdsession);
610
return {
7-
course: await (await listContent({ contentType: ContentType.course, limit: 3 })).content,
8-
tutorial: await (await listContent({ contentType: ContentType.tutorial, limit: 3 })).content,
9-
podcast: await (await listContent({ contentType: ContentType.podcast, limit: 3 })).content,
10-
post: await (await listContent({ contentType: ContentType.post, limit: 3 })).content
11+
user: decodedClaims
1112
};
1213
}) satisfies LayoutServerLoad;

apps/codingcatdev/src/routes/+layout.svelte

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
<script lang="ts">
2+
import type { LayoutData } from './$types';
3+
export let data: LayoutData;
4+
5+
console.log(data);
6+
27
// Core
38
import { page } from '$app/stores';
49
import { afterNavigate } from '$app/navigation';
@@ -8,12 +13,12 @@
813
import '../app.postcss';
914
1015
// BlackCatUI Components
11-
import { AppShell } from '@codingcatdev/blackcatui';
16+
import { AppShell, Modal, Toast } from '@codingcatdev/blackcatui';
1217
1318
// CodingCat.Dev Components
14-
import MyAppBar from './(layout-partials)/CcdAppBar.svelte';
15-
import MyDrawer from './(layout-partials)/CcdDrawer.svelte';
16-
import MyFooter from './(layout-partials)/CcdFooter.svelte';
19+
import CcdAppBar from './(layout-partials)/CcdAppBar.svelte';
20+
import CcdDrawer from './(layout-partials)/CcdDrawer.svelte';
21+
import CcdFooter from './(layout-partials)/CcdFooter.svelte';
1722
1823
// Scroll heading into view
1924
function scrollHeadingIntoView(): void {
@@ -101,12 +106,14 @@
101106
</svelte:head>
102107

103108
<!-- Overlays -->
104-
<MyDrawer />
109+
<CcdDrawer />
110+
<Modal />
111+
<Toast />
105112

106113
<!-- App Shell -->
107114
<AppShell regionPage="overflow-y-scroll" slotPageFooter="pt-4 bg-surface-50-900-token" }>
108115
<!-- Header -->
109-
<svelte:fragment slot="bcu-app-shell-header"><MyAppBar /></svelte:fragment>
116+
<svelte:fragment slot="bcu-app-shell-header"><CcdAppBar /></svelte:fragment>
110117

111118
<!-- Sidebar (Left) -->
112119
<!-- <svelte:fragment slot="bcu-app-shell-sidebar-left">
@@ -117,5 +124,5 @@
117124
<slot />
118125

119126
<!-- Page Footer -->
120-
<svelte:fragment slot="bcu-app-shell-page-footer"><MyFooter /></svelte:fragment>
127+
<svelte:fragment slot="bcu-app-shell-page-footer"><CcdFooter /></svelte:fragment>
121128
</AppShell>

0 commit comments

Comments
 (0)