using firebase auth
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'uno.css';
|
||||
import createVueApp from '@/shared/createVueApp';
|
||||
import 'uno.css';
|
||||
|
||||
async function render() {
|
||||
const { app, router } = createVueApp();
|
||||
router.isReady().then(() => {
|
||||
|
||||
46
src/client/lib/firebase.ts
Normal file
46
src/client/lib/firebase.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { initializeApp } from "firebase/app";
|
||||
import { createUserWithEmailAndPassword, getAuth, GoogleAuthProvider, sendPasswordResetEmail, signInWithEmailAndPassword, signInWithPopup } from "firebase/auth";
|
||||
// TODO: Add SDKs for Firebase products that you want to use
|
||||
// https://firebase.google.com/docs/web/setup#available-libraries
|
||||
|
||||
// Your web app's Firebase configuration
|
||||
const firebaseConfig = {
|
||||
apiKey: "AIzaSyBTr0L5qxdrVEtWuP2oAicJXQvVyeXkMts",
|
||||
authDomain: "trello-7ea39.firebaseapp.com",
|
||||
projectId: "trello-7ea39",
|
||||
storageBucket: "trello-7ea39.firebasestorage.app",
|
||||
messagingSenderId: "321067890572",
|
||||
appId: "1:321067890572:web:e34e1e657125d37be688a9"
|
||||
};
|
||||
|
||||
// Initialize Firebase
|
||||
const appFirebase = initializeApp(firebaseConfig);
|
||||
const provider = new GoogleAuthProvider();
|
||||
const auth = getAuth(appFirebase);
|
||||
export const googleAuth = signInWithPopup(auth, provider).then((result) => {
|
||||
console.log('User signed in:', result.user);
|
||||
})
|
||||
export const emailAuth = (username: string, password: string) => {
|
||||
return signInWithEmailAndPassword(auth, username, password)
|
||||
}
|
||||
export const forgotPassword = (email: string) => {
|
||||
return sendPasswordResetEmail(auth, email)
|
||||
.then(() => {
|
||||
console.log('Password reset email sent');
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error sending password reset email:', error);
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
export const signUp = (email: string, password: string) => {
|
||||
return createUserWithEmailAndPassword(auth, email, password)
|
||||
.then((userCredential) => {
|
||||
console.log('User signed up:', userCredential.user);
|
||||
return userCredential.user;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error signing up:', error);
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
@@ -1,14 +1,9 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { client } from '@/client/api/rpcclient';
|
||||
import { User } from 'firebase/auth';
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref } from 'vue';
|
||||
|
||||
interface User {
|
||||
id: string;
|
||||
username: string;
|
||||
email: string;
|
||||
name: string;
|
||||
}
|
||||
import { useRouter } from 'vue-router';
|
||||
import { emailAuth, signUp } from '../lib/firebase';
|
||||
|
||||
export const useAuthStore = defineStore('auth', () => {
|
||||
const user = ref<User | null>(null);
|
||||
@@ -22,31 +17,31 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
async function init() {
|
||||
if (initialized.value) return;
|
||||
|
||||
try {
|
||||
const response = await client.checkAuth();
|
||||
if (response.authenticated && response.user) {
|
||||
user.value = response.user;
|
||||
// Get CSRF token if authenticated
|
||||
try {
|
||||
const csrfResponse = await client.getCSRFToken();
|
||||
csrfToken.value = csrfResponse.csrfToken;
|
||||
} catch (e) {
|
||||
// CSRF token might not be available yet
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Not authenticated, that's fine
|
||||
} finally {
|
||||
initialized.value = true;
|
||||
}
|
||||
// try {
|
||||
// const response = await client.checkAuth();
|
||||
// if (response.authenticated && response.user) {
|
||||
// user.value = response.user;
|
||||
// // Get CSRF token if authenticated
|
||||
// try {
|
||||
// const csrfResponse = await client.getCSRFToken();
|
||||
// csrfToken.value = csrfResponse.csrfToken;
|
||||
// } catch (e) {
|
||||
// // CSRF token might not be available yet
|
||||
// }
|
||||
// }
|
||||
// } catch (e) {
|
||||
// // Not authenticated, that's fine
|
||||
// } finally {
|
||||
// initialized.value = true;
|
||||
// }
|
||||
}
|
||||
|
||||
async function login(username: string, password: string) {
|
||||
loading.value = true;
|
||||
error.value = null;
|
||||
return client.login(username, password).then((response) => {
|
||||
user.value = response.user;
|
||||
csrfToken.value = response.csrfToken;
|
||||
return emailAuth(username, password).then((userCredential) => {
|
||||
user.value = userCredential.user;
|
||||
// csrfToken.value = userCredential.csrfToken;
|
||||
router.push('/');
|
||||
}).catch((e: any) => {
|
||||
// error.value = e.message || 'Login failed';
|
||||
@@ -60,7 +55,7 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
async function register(username: string, email: string, password: string) {
|
||||
loading.value = true;
|
||||
error.value = null;
|
||||
return client.register({ username, email, password }).then((response) => {
|
||||
return signUp(email, password).then((response) => {
|
||||
user.value = response.user;
|
||||
csrfToken.value = response.csrfToken;
|
||||
router.push('/');
|
||||
|
||||
27
src/main.ts
27
src/main.ts
@@ -5,13 +5,28 @@ import { contextStorage } from "hono/context-storage";
|
||||
import isMobile from "is-mobile";
|
||||
import { AppModule } from "./server/app.module";
|
||||
import { HonoAdapter, NestHonoApplication } from "./server/common/adapter/hono";
|
||||
import { CustomZodValidationPipe } from "./server/common/pipes/CustomZodValidation.pipe";
|
||||
import { ssrRender } from "./server/HonoAdapter/ssrRender";
|
||||
import { TransformInterceptor } from "./server/common/interceptor/transform.interceptor";
|
||||
import { ZodValidationPipe } from "nestjs-zod";
|
||||
declare global {
|
||||
var __APP__: {
|
||||
app?: NestHonoApplication;
|
||||
hono?: Hono;
|
||||
server?: Bun.Server<any>;
|
||||
} | undefined;
|
||||
}
|
||||
if (!globalThis.__APP__) {
|
||||
globalThis.__APP__ = {};
|
||||
}
|
||||
if (globalThis.__APP__.app) {
|
||||
await globalThis.__APP__.app.close();
|
||||
}
|
||||
let serve: Bun.Server<undefined> | any = {
|
||||
stop: async () => {},
|
||||
}
|
||||
const hono = new Hono();
|
||||
globalThis.__APP__.hono = hono;
|
||||
|
||||
const app = await NestFactory.create<NestHonoApplication>(
|
||||
AppModule,
|
||||
new HonoAdapter({
|
||||
@@ -34,11 +49,16 @@ const app = await NestFactory.create<NestHonoApplication>(
|
||||
},
|
||||
})
|
||||
);
|
||||
globalThis.__APP__.app = app;
|
||||
app.setGlobalPrefix("api");
|
||||
app.enableShutdownHooks();
|
||||
app.useGlobalPipes(new CustomZodValidationPipe());
|
||||
// Validation Pipe (Zod) and Transform Interceptor
|
||||
app.useGlobalInterceptors(new TransformInterceptor());
|
||||
app.useGlobalPipes(new ZodValidationPipe());
|
||||
|
||||
app.useStaticAssets("/*", { root: "./dist/client" });
|
||||
await app.init();
|
||||
// Hono Zone Middleware
|
||||
hono.use(async (c, next) => {
|
||||
c.set("fetch", hono.request.bind(hono));
|
||||
const ua = c.req.header("User-Agent");
|
||||
@@ -48,9 +68,6 @@ hono.use(async (c, next) => {
|
||||
c.set("isMobile", isMobile({ ua }));
|
||||
await next();
|
||||
}, contextStorage());
|
||||
|
||||
app.useStaticAssets("/*", { root: "./dist/client" });
|
||||
await app.init();
|
||||
hono.get("/.well-known/*", (c) => {
|
||||
return c.json({ ok: true });
|
||||
});
|
||||
|
||||
@@ -2,10 +2,8 @@ import { MiddlewareConsumer, Module, NestModule } from "@nestjs/common";
|
||||
import { APP_FILTER } from "@nestjs/core";
|
||||
import { HttpExceptionFilter } from "./common/filter/http-exception.filter";
|
||||
import { LoggerMiddleware } from "./middleware";
|
||||
import { AuthModule } from "./modules/auth/auth.module";
|
||||
|
||||
@Module({
|
||||
imports: [AuthModule],
|
||||
providers: [
|
||||
{
|
||||
provide: APP_FILTER,
|
||||
|
||||
@@ -1,24 +1,18 @@
|
||||
import {
|
||||
CallHandler,
|
||||
ExecutionContext,
|
||||
Injectable,
|
||||
NestInterceptor,
|
||||
} from '@nestjs/common';
|
||||
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Response } from '../interfaces/response.interface';
|
||||
import { InternalHonoRes } from '../adapter/hono/_util';
|
||||
|
||||
@Injectable()
|
||||
export class TransformInterceptor<T>
|
||||
implements NestInterceptor<T, any>
|
||||
{
|
||||
intercept(
|
||||
context: ExecutionContext,
|
||||
next: CallHandler,
|
||||
) {
|
||||
return next.handle().pipe(
|
||||
map((data) => ({
|
||||
success: true,
|
||||
data,
|
||||
})),
|
||||
);
|
||||
}
|
||||
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
|
||||
intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
|
||||
return next.handle().pipe(
|
||||
map(data => ({
|
||||
statusCode: context.switchToHttp().getResponse<InternalHonoRes>().res.status,
|
||||
message: 'Success',
|
||||
data,
|
||||
})),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
12
src/server/common/interfaces/response.interface.ts
Normal file
12
src/server/common/interfaces/response.interface.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
// import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class Response<T> {
|
||||
// @ApiProperty()
|
||||
statusCode: number = 200;
|
||||
|
||||
// @ApiProperty()
|
||||
message: string = 'Success';
|
||||
|
||||
// @ApiProperty()
|
||||
data: T = {} as T;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import { Controller, Get } from "@nestjs/common";
|
||||
|
||||
@Controller('auth')
|
||||
export class AuthController {
|
||||
constructor() {}
|
||||
|
||||
@Get('/')
|
||||
index() {
|
||||
return { message: 'Auth Controller is working' };
|
||||
// throw new Error('Not implemented');
|
||||
// return 'Hello Auth';
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { AuthController } from './auth.controller';
|
||||
import { AuthService } from './auth.service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
// hono-di:imports
|
||||
],
|
||||
controllers: [
|
||||
AuthController, // hono-di:controllers
|
||||
],
|
||||
providers: [
|
||||
AuthService, // hono-di:providers
|
||||
],
|
||||
})
|
||||
export class AuthModule {}
|
||||
@@ -1,6 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
constructor() {}
|
||||
}
|
||||
9
src/type.d.ts
vendored
9
src/type.d.ts
vendored
@@ -7,4 +7,11 @@ declare module "@httpClientAdapter" {
|
||||
url: string;
|
||||
pathsForGET?: string[];
|
||||
}): TinyRpcClientAdapter;
|
||||
}
|
||||
}
|
||||
declare global {
|
||||
var __APP__: {
|
||||
app?: NestHonoApplication;
|
||||
hono?: Hono;
|
||||
server?: Bun.Server;
|
||||
} | undefined;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user