Skip to content

Commit

Permalink
Working on global auth, Student, Teacher, Client considered usable pr…
Browse files Browse the repository at this point in the history
…ofiles
  • Loading branch information
vvaldesc committed May 13, 2024
1 parent 2901ade commit 1d47698
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 78 deletions.
22 changes: 22 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
**/.git
**/.svn
**/.hg
**/node_modules

# Ignore the build directory
build/

# Ignore the dist directory
dist/

# Ignore the coverage directory
coverage/

# Ignore the .idea directory
.idea/

# Ignore the .vscode directory
.vscode/

./src/pages/404.js
./src/pages/profile.js
2 changes: 1 addition & 1 deletion src/components/Headernav.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
import Button from "@/components/buttons/Button.astro";
import Button from "@/components/Buttons/Button.astro";
interface Props {
fields: string[];
}
Expand Down
63 changes: 60 additions & 3 deletions src/consts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export interface Client {
id: number;
name?: string;
surname?: string;
email: string;
phone_number: string;
email?: string;
phone_number?: string;
address?: string;
city?: string;
bornDate?: Date;
Expand All @@ -29,7 +29,50 @@ export interface Client {
active?: boolean;
}

export interface Student {
id: number;
matriculation_number: string;
DNI: string;
employed?: boolean;
educational_level: string;
name?: string;
surname?: string;
email: string;
phone_number: string;
address: string;
city: string;
bornDate: Date;
created_at: Date;
updated_at?: Date;
username: string;
password: string;
confirmed: boolean;
image: string;
active?: boolean;
}

export interface Teacher {
id: number;
is_admin?: boolean;
name?: string;
surname?: string;
email: string;
phone_number: string;
address: string;
city: string;
bornDate: Date;
created_at: Date;
updated_at?: Date;
username: string;
password: string;
confirmed: boolean;
image?: string;
active?: boolean;
}


export type ClientSession = { OAuth: Session } & { client: Client } & { profilePhotoSrc: string } & { role: string };
export type ProfileSession = { OAuth: Session } & { profile: Client | Student | Teacher } & { profilePhotoSrc: string } & { role: string };

export enum SessionState {
WithoutSession = 0,
Expand All @@ -38,6 +81,20 @@ export enum SessionState {
}

export interface sessionInfoState {
sessionInfo: ClientSession;
sessionInfo: ProfileSession;
sessionState: SessionState;
}

export interface Result {
data: any,
table: string,
count: number
}

export interface SqlProfileByEmail {
columns: string[];
columnTypes: string[];
rows: Array<Array<number | string>>;
rowsAffected: number;
lastInsertRowid: null;
}
41 changes: 19 additions & 22 deletions src/pages/401.astro
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
---
title: "Página no encontrada"
import Layout from "@/layouts/Layout.astro"
title: "Página no encontrada";
import Layout from "@/layouts/Layout.astro";
//Session handling//////////////////////////// prettier-ignore
import {validateOAuth} from "@/services/server_side_logic"; // prettier-ignore
import { getSession } from "auth-astro/server"; // prettier-ignore
import type {SessionState} from "@/consts/types"; // prettier-ignore
import type { Session } from "@auth/core/types"; // prettier-ignore
const session: Session = (await getSession(Astro.request)) as Session; // prettier-ignore
const sessionState: SessionState = validateOAuth(session) ? 1 : 0; // prettier-ignore
//End handling//////////////////////////
import type {
SessionState,
} from "@/consts/types";
import type { Session } from "@auth/core/types";
import {
validateOAuth
} from "@/services/server_side_logic";
import { getSession } from "auth-astro/server";
const session: Session = await getSession(Astro.request) as Session;
const sessionState: SessionState = validateOAuth(session) ? 1 : 0;
const title: string = sessionState === 0 ? "Registrate en Imagen" : "Completa tu registro";
const title: string =sessionState === 0 ? "Registrate en Imagen" : "Completa tu registro"; // prettier-ignore
---

<Layout title={title}>
{
sessionState === 1
? <p>Necesitas completar tu registro</p>
: <p>Necesitas registrarte</p>
}
{
sessionState === 1 ? (
<p>Necesitas completar tu registro</p>
) : (
<p>Necesitas registrarte</p>
)
}
</Layout>
2 changes: 1 addition & 1 deletion src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Section_plans from "@/sections/Section_plans.astro";
import Animated_main_div from "@/components/Animated_main_div.astro";
import Main from "@/components/Main.astro";
import Div_images from "@/components/Div_images.astro";
import Button_suggestion from "@/components/buttons/Button_suggestion.astro";
import Button_suggestion from "@/components/Buttons/Button_suggestion.astro";
import Google_map from "@/components/Google_Map/Google_map.astro";
import main_promo from "@/consts/main_promo.json";
Expand Down
50 changes: 23 additions & 27 deletions src/pages/profile.astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,44 @@ import Layout from "@/layouts/Layout.astro";
import Main from "@/components/Main.astro";
import Profile_section from "@/sections/Profile_section.astro";
//Session handling//////////////////////////
import type {
ClientSession,
SessionState,
sessionInfoState,
} from "@/consts/types";
import {
sessionHandler,
sessionStateCheck,
} from "@/services/server_side_logic";
import { getSession } from "auth-astro/server";
let sessionInfoState: sessionInfoState = {} as sessionInfoState;
//Session handling//////////////////////////// prettier-ignore
import {sessionHandler,sessionStateCheck} from "@/services/server_side_logic"; // prettier-ignore
import {getSession} from "auth-astro/server"; // prettier-ignore
import type {ProfileSession,SessionState,sessionInfoState} from "@/consts/types"; // prettier-ignore
let sessionInfoState: sessionInfoState = {} as sessionInfoState; // prettier-ignore
// prettier-ignore
try {
const sessionInfo: ClientSession = await sessionHandler(await getSession(Astro.request));
const sessionInfo: ProfileSession = await sessionHandler(await getSession(Astro.request));
const sessionState: SessionState = await sessionStateCheck(sessionInfo);
sessionInfoState = { sessionState, sessionInfo };
console.log(sessionInfoState);
if (
sessionInfoState.sessionState === 1 ||
sessionInfoState.sessionState === 0
) {
if ( sessionInfoState.sessionState === 1 || sessionInfoState.sessionState === 0 ) {
return Astro.rewrite("/401");
}
} catch (error) {
console.error(error);
}
//End session handling///////////////////////
//End handling//////////////////////////
const userName = sessionInfoState.sessionInfo.client?.username || sessionInfoState.sessionInfo.OAuth.user?.name || "a Imagen";
const userName =
sessionInfoState.sessionInfo.profile?.username ||
sessionInfoState.sessionInfo.OAuth.user?.name ||
"a Imagen";
---

<Layout title=`Bienvenido ${userName}`>
<Main>
<Profile_section profilePhotoSrc={sessionInfoState.sessionInfo.profilePhotoSrc}>
<Profile_section
profilePhotoSrc={sessionInfoState.sessionInfo.profilePhotoSrc}
>
<h1 slot="header">Este es el encabezado</h1>
<p>{sessionInfoState.sessionInfo.role}</p>
<p>Este es el contenido principal</p>
<p slot="user">usuario: {sessionInfoState.sessionInfo.client?.username}</p>
<p slot="id">id: {sessionInfoState.sessionInfo.client?.id}</p>
<p slot="mail">mail: {sessionInfoState.sessionInfo.client?.email}</p>
<p slot="user">
usuario: {sessionInfoState.sessionInfo.profile?.username}
</p>
<p slot="id">id: {sessionInfoState.sessionInfo.profile?.id}</p>
<p slot="mail">mail: {sessionInfoState.sessionInfo.profile?.email}</p>
</Profile_section>
</Main>
</Layout>
</Layout>
2 changes: 1 addition & 1 deletion src/sections/Section_plans.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
import Button_animated_promo from "@/components/buttons/Button_animated_promo.astro";
import Button_animated_promo from "@/components/Buttons/Button_animated_promo.astro";
---

<section class="w-full bg-current colored-bg flex justify-evenly p-10">
Expand Down
41 changes: 35 additions & 6 deletions src/services/server_side_fetch.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,52 @@
import type { Client } from "@/consts/types";
import type { Client, Result, Teacher, Student } from "@/consts/types";

export const fetchClientById = async (id: number): Promise<Client | undefined> => {
try {
const response = await fetch(`http:https://localhost:4321/api/clients/id/${id}`);
const data: any = await response.json();
const client: Client = await data.result[0];
const data = await response.json();
const result: Result = data.result as Result;
const client: Client = await result.data[0];
return client;
} catch (error) {
console.error("Error fetching client data:", error);
}
};

export const fetchClientByEmail = async (email: string): Promise<Client | undefined> => {
export const fetchClientByEmail = async (email: string): Promise<Client | Teacher | Student | undefined> => {
try {
const response = await fetch(`http:https://localhost:4321/api/clients/email/${email}`);
const data: any = await response.json();
const client: Client = await data.result[0];
const data = await response.json();
const result: Result = data.result as Result;
if (data.count > 1)
throw new Error("Query by unique key returned more than one registers.");
const client: Client = await result.data[0];
return client;
} catch (error) {
console.error("Error fetching client data:", error);
}
};

export const fetchProfileByEmail = async (email: string): Promise<{profile: Client | Student | Teacher | undefined; table: string}> => {
try {
const response = await fetch(`http:https://localhost:4321/api/misc/profile/email/${email}`);// BD petition
let data = await response.json();
const result: Result = data.result as Result;
if (data.count > 1)
throw new Error("Query by unique key returned more than one registers.");
const id: number = result.data.rows[0][0] as number;
const table: string = result.data.rows[0][1] as string;
console.log("Profile fetched by email: ", id, table);
switch (table) {
case "Clients":
return {
profile: await fetchClientById(id),
table: table
};// BD petition
default:
throw new Error("Role not found.");
}
} catch (error) {
console.error("Error fetching client data:", error);
}
return {profile: undefined, table: ""};
};
34 changes: 17 additions & 17 deletions src/services/server_side_logic.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//import type { Client } from "@/consts/types";
import type { Session } from "@auth/core/types";
import type { ClientSession, Client } from "@/consts/types";
import type { ClientSession, Client, Teacher, Student, ProfileSession } from "@/consts/types";
import { SessionState } from "@/consts/types";

import { fetchClientByEmail } from "@/services/server_side_fetch";
import { fetchProfileByEmail } from "@/services/server_side_fetch";

export function validateOAuth(session: Session | null): boolean {
if (!session) {
Expand All @@ -29,12 +29,11 @@ export function validateOAuth(session: Session | null): boolean {
return true;
}


export const sessionHandler = async (session: Session | null): Promise<ClientSession> => {
let result: ClientSession = {
export const sessionHandler = async (session: Session | null): Promise<ProfileSession> => {
let result: ProfileSession = {
OAuth: {} as Session,
client: {} as Client,
role: "client" as string,
profile: {} as Client | Student | Teacher,
role: "" as string,
profilePhotoSrc: "" as string,
};
// If google login doesn't return name or email
Expand All @@ -43,32 +42,33 @@ export const sessionHandler = async (session: Session | null): Promise<ClientSes
return result;
}
result.OAuth = session as Session;
// Fetch client by email from web database
const client = await fetchClientByEmail(session?.user?.email as string);
console.log("Session data: ", session);
// Fetch profile by email from web database
const {profile , table} = await fetchProfileByEmail(session?.user?.email as string);
console.log("Client fetched by email: ", profile);
// If client is registered
if (client) {
const profilePhotoSrc: string = client.image || session?.user?.image || "/images/default_profile.png";
result.client = client;
if (profile) {
const profilePhotoSrc: string = profile.image || session?.user?.image || "/images/default_profile.png";
result.profile = profile;
result.profilePhotoSrc = profilePhotoSrc;
result.role = table;
return result;
} else {
console.log("Client is not registered in web database.");
return result;
}
};

export async function sessionStateCheck(sessionInfo: ClientSession): Promise<SessionState> {
export async function sessionStateCheck(sessionInfo: ProfileSession): Promise<SessionState> {
try {
if (!sessionInfo.OAuth) {
if (!sessionInfo.OAuth || !sessionInfo.OAuth.user?.name || !sessionInfo.OAuth.user.email) {
console.error("No hay sesión activa OAuth.");
return SessionState.WithoutSession;
}

if (sessionInfo.client == null || !sessionInfo.client.id || !sessionInfo.client.email) {
if (sessionInfo.profile == null || !sessionInfo.profile.id || !sessionInfo.profile.email) {
console.error("El cliente tiene sesión OAuth pero necesita registrarse");
return SessionState.NeedsRegister;
}

return SessionState.Registered;
} catch (error) {
console.error(error);
Expand Down

0 comments on commit 1d47698

Please sign in to comment.