Skip to content

Commit

Permalink
feat: firebase setup
Browse files Browse the repository at this point in the history
  • Loading branch information
yjose committed Sep 16, 2024
1 parent e583721 commit a265bc6
Show file tree
Hide file tree
Showing 19 changed files with 1,016 additions and 174 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ pnpm-debug.log*
# jetbrains setting folder
.idea/
coverage/
.env*
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"firebase": "^10.12.2",
"firebase-admin": "^12.5.0",
"lucide-react": "^0.436.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand Down
778 changes: 774 additions & 4 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

16 changes: 0 additions & 16 deletions src/actions/createAccount.ts

This file was deleted.

11 changes: 4 additions & 7 deletions src/actions/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { createAccount } from "./createAccount";
import { loginAccount } from "./loginAccount";
import { logoutAccount } from "./logoutAccount";

import { initSession } from "./init-session";
import { removeSession } from "./remove-session";
export const server = {
createAccount,
loginAccount,
logoutAccount
initSession,
removeSession,
};
50 changes: 50 additions & 0 deletions src/actions/init-session.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { app } from "@/firebase/server";
import { defineAction } from "astro:actions";
import { getAuth } from "firebase-admin/auth";
import { z } from "astro:schema";

export const initSession = defineAction({
accept: "json",
input: z.object({
idToken: z.string(),
}),
handler: async ({ idToken }, { cookies }) => {
const auth = getAuth(app);
if (!idToken) {
return {
error: "No idToken provided",
};
}
/* Verify id token */
try {
const decodedToken = await auth.verifyIdToken(idToken);
console.log("Decoded token:", decodedToken);
} catch (error) {
console.error("Error verifying id token:", error);
return {
error: "Invalid id token",
};
}

try {
// Create and set session cookie
const fiveDays = 60 * 60 * 24 * 5 * 1000;
const sessionCookie = await auth.createSessionCookie(idToken, {
expiresIn: fiveDays,
});

cookies.set("__session", sessionCookie, {
path: "/",
});

return {
success: true,
};
} catch (error) {
console.error("Error signing in:", error);
return {
error: "Error signing in",
};
}
}
});
16 changes: 0 additions & 16 deletions src/actions/loginAccount.ts

This file was deleted.

8 changes: 0 additions & 8 deletions src/actions/logoutAccount.ts

This file was deleted.

14 changes: 14 additions & 0 deletions src/actions/remove-session.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { defineAction } from "astro:actions";

export const removeSession = defineAction({
accept: "json",
handler: async (_input, { cookies }) => {
cookies.delete("__session", {
path: "/",
});

return {
success: true,
};
},
});
26 changes: 25 additions & 1 deletion src/env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,30 @@

declare namespace App {
interface Locals {
userEmail: string | null;
userUid: string | null;
}
}

interface ImportMetaEnv {
// Server-side variables
readonly FIREBASE_PRIVATE_KEY_ID: string;
readonly FIREBASE_PRIVATE_KEY: string;
readonly FIREBASE_PROJECT_ID: string;
readonly FIREBASE_CLIENT_EMAIL: string;
readonly FIREBASE_CLIENT_ID: string;
readonly FIREBASE_AUTH_URI: string;
readonly FIREBASE_TOKEN_URI: string;
readonly FIREBASE_AUTH_CERT_URL: string;
readonly FIREBASE_CLIENT_CERT_URL: string;

// Client-side variables
readonly PUBLIC_FIREBASE_API_KEY: string;
readonly PUBLIC_FIREBASE_AUTH_DOMAIN: string;
readonly PUBLIC_FIREBASE_STORAGE_BUCKET: string;
readonly PUBLIC_FIREBASE_MESSAGING_SENDER_ID: string;
readonly PUBLIC_FIREBASE_APP_ID: string;
}

interface ImportMeta {
readonly env: ImportMetaEnv;
}
15 changes: 15 additions & 0 deletions src/firebase/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Client-side Firebase initialization
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";

const firebaseConfig = {
apiKey: import.meta.env.PUBLIC_FIREBASE_API_KEY,
authDomain: import.meta.env.PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: import.meta.env.PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: import.meta.env.PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: import.meta.env.PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: import.meta.env.PUBLIC_FIREBASE_APP_ID
};

export const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
20 changes: 0 additions & 20 deletions src/firebase/config.ts

This file was deleted.

31 changes: 31 additions & 0 deletions src/firebase/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { ServiceAccount } from "firebase-admin";
import { initializeApp, cert, getApps } from "firebase-admin/app";

const activeApps = getApps();

const serviceAccount = {
type: "service_account",
project_id: import.meta.env.FIREBASE_PROJECT_ID,
private_key_id: import.meta.env.FIREBASE_PRIVATE_KEY_ID,
private_key: import.meta.env.FIREBASE_PRIVATE_KEY,
client_email: import.meta.env.FIREBASE_CLIENT_EMAIL,
client_id: import.meta.env.FIREBASE_CLIENT_ID,
auth_uri: import.meta.env.FIREBASE_AUTH_URI,
token_uri: import.meta.env.FIREBASE_TOKEN_URI,
auth_provider_x509_cert_url: import.meta.env.FIREBASE_AUTH_CERT_URL,
client_x509_cert_url: import.meta.env.FIREBASE_CLIENT_CERT_URL,
};

const initApp = () => {
if (import.meta.env.PROD) {
console.info('PROD env detected. Using default service account.')
// Use default config in firebase functions. Should be already injected in the server by Firebase.
return initializeApp()
}
console.info('Loading service account from env.')
return initializeApp({
credential: cert(serviceAccount as ServiceAccount)
})
}

export const app = activeApps.length === 0 ? initApp() : activeApps[0];
26 changes: 0 additions & 26 deletions src/middleware.ts

This file was deleted.

49 changes: 49 additions & 0 deletions src/pages/before-start.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
import Button from "@/components/button.astro";
import BaseLayout from "@/layouts/layout.astro";
---

<BaseLayout>
<div class="max-w-2xl mx-auto py-8 px-4">
<div class="bg-white shadow-md rounded-lg p-6">
<h2 class="text-xl font-semibold mb-4">Survey Rules</h2>
<ul class="list-disc pl-6 mb-6 space-y-2">
<li>Answer all questions honestly and to the best of your ability.</li>
<li>Complete the survey in one sitting; it should take about 15 minutes.</li>
<li>Ensure you have a stable internet connection.</li>
<li>Your responses are confidential and will be used for research purposes only.</li>
<li>You may exit the survey at any time, but your progress won't be saved.</li>
</ul>
<Button intent="accent" class="w-full">Start Survey</Button>
</div>
</div>
</BaseLayout>

<script>
import { actions } from "astro:actions";
import { signInAnonymously } from "firebase/auth";
import { auth } from "@/firebase/client";

const startButton = document.querySelector("button") as HTMLButtonElement;

startButton.addEventListener("click", async () => {
try {
const userCredential = await signInAnonymously(auth);
const token = await userCredential.user.getIdToken();
console.log(token);

const { error } = await actions.initSession({idToken: token})

if (error) {
console.error("Error initializing session:", error);
return;
}

// Redirect to the survey page or reload as needed
window.location.href = "/survey";
} catch (error) {
console.error("Error during anonymous login:", error);
}
});
</script>

34 changes: 0 additions & 34 deletions src/pages/home.astro

This file was deleted.

2 changes: 1 addition & 1 deletion src/pages/login.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
import Button from "@/components/Button.astro";
import Button from "@/components/button.astro";
import Input from "@/components/Input.astro";
import BaseLayout from "@/layouts/layout.astro";
---
Expand Down
41 changes: 0 additions & 41 deletions src/pages/new.astro

This file was deleted.

Loading

0 comments on commit a265bc6

Please sign in to comment.