8 Commits

Author SHA1 Message Date
02e84ed9d6 login okay
Some checks failed
Build Docker Image / run (push) Failing after 30s
2024-04-26 16:00:53 +02:00
06bdeff188 add PB middleware
All checks were successful
Build Docker Image / run (push) Successful in 53s
2024-04-26 14:18:46 +02:00
7a510a53a1 rm email visibility
All checks were successful
Build Docker Image / run (pull_request) Successful in 1m16s
Build Docker Image / run (push) Successful in 27s
2024-04-26 10:46:35 +02:00
063660db9d fix userObj type 2024-04-26 10:46:26 +02:00
55740b6219 fix error issue 2024-04-26 10:44:16 +02:00
459c1252e0 update package 2024-04-26 10:41:54 +02:00
cd234f5b37 rm usless thing 2024-04-26 10:41:37 +02:00
76755baa1d fix: make some build fix
Some checks failed
Build Docker Image / run (pull_request) Failing after 31s
2024-04-25 19:52:01 +02:00
12 changed files with 205 additions and 782 deletions

9
front/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,9 @@
{
"editor.quickSuggestions": {
"strings": "on"
},
"tailwindCSS.includeLanguages": {
"astro": "html"
},
"typescript.tsdk": "node_modules/typescript/lib"
}

View File

@ -1,12 +1,11 @@
import { defineConfig } from 'astro/config'; import node from '@astrojs/node'
import node from '@astrojs/node'; import tailwind from '@astrojs/tailwind'
import tailwind from "@astrojs/tailwind"; import { defineConfig } from 'astro/config'
import react from "@astrojs/react"; import react from '@astrojs/react'
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({
// integrations: [tailwind(), test, routing(), version(), buildInfos()],
compressHTML: true, compressHTML: true,
build: { build: {
assets: 'assets', assets: 'assets',
@ -27,4 +26,4 @@ export default defineConfig({
include: ['leaflet'] include: ['leaflet']
} }
} }
}); })

746
front/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,6 @@
"type": "module", "type": "module",
"version": "0.0.1", "version": "0.0.1",
"private": "true", "private": "true",
"private": "true",
"scripts": { "scripts": {
"dev": "astro dev", "dev": "astro dev",
"start": "node ./dist/server/entry.mjs", "start": "node ./dist/server/entry.mjs",
@ -28,10 +27,11 @@
"react-leaflet": "^4.2.1", "react-leaflet": "^4.2.1",
"simple-icons-astro": "^11.12.0", "simple-icons-astro": "^11.12.0",
"tailwindcss": "^3.4.3", "tailwindcss": "^3.4.3",
"typescript": "^5.2.2" "typescript": "^5"
}, },
"devDependencies": { "devDependencies": {
"@astrojs/check": "^0", "@astrojs/check": "^0",
"@astrojs/ts-plugin": "^1.6.1",
"@types/leaflet": "^1.9.12", "@types/leaflet": "^1.9.12",
"@types/node": "^20", "@types/node": "^20",
"@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/eslint-plugin": "^6.21.0",

15
front/src/env.d.ts vendored
View File

@ -1,12 +1,14 @@
/// <reference path="../.astro/types.d.ts" /> /// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" /> /// <reference types="astro/client" />
import PocketBase from 'pocketbase'
export interface ImportMetaEnv { export interface ImportMetaEnv {
NODE_ENV: string NODE_ENV: string
APP_URL: string APP_URL: string
POCKETBASEURL: string POCKETBASE_URL: string
GOOGLE_API_KEY: string
} }
interface ImportMeta { interface ImportMeta {
@ -14,9 +16,10 @@ interface ImportMeta {
} }
// eslint-disable-next-line @typescript-eslint/no-namespace
declare namespace App { declare namespace App {
/** // eslint-disable-next-line @typescript-eslint/no-empty-interface
* Middlewares variables export interface Locals {
*/ pb: PocketBase
interface Locals {} }
} }

View File

@ -1,10 +1,10 @@
import { AstroCookies } from 'astro' import type { AstroCookies } from 'astro'
import type UserObj from 'models/User'
import PocketBase from 'pocketbase' import PocketBase from 'pocketbase'
import UserObj from 'models/User'
import { getEnv } from 'libs/Env' import { getEnv } from 'libs/Env'
const pb = new PocketBase(getEnv('POCKET_BASE','https://pb-tweb.cb85.fr')) // XXX: 'https://pb-tweb.cb85.fr' const pb = new PocketBase(getEnv('POCKETBASE_URL','https://pb-tweb.cb85.fr')) // XXX: 'https://pb-tweb.cb85.fr'
export async function clearUser(cookies: AstroCookies): Promise<void> { export async function clearUser(cookies: AstroCookies): Promise<void> {
const sessionID = cookies.get('session')?.value const sessionID = cookies.get('session')?.value
@ -18,7 +18,7 @@ export async function clearUser(cookies: AstroCookies): Promise<void> {
}) })
} }
export async function login(cookies: AstroCookies, user: {user: string, password: string}): boolean { export async function login(cookies: AstroCookies, user: {user: string, password: string}): Promise<boolean> {
const authData = await pb.collection('users').authWithPassword(user.user, user.password) const authData = await pb.collection('users').authWithPassword(user.user, user.password)
@ -33,7 +33,7 @@ export async function login(cookies: AstroCookies, user: {user: string, password
httpOnly: true, httpOnly: true,
path: '/', path: '/',
secure: secure, secure: secure,
sameSite: 'Strict', sameSite: 'strict',
maxAge: 365000, maxAge: 365000,
}) })
return true return true
@ -44,15 +44,40 @@ export async function login(cookies: AstroCookies, user: {user: string, password
export async function getUser(cookies: AstroCookies): Promise<UserObj | null> { export async function getUser(cookies: AstroCookies): Promise<UserObj | null> {
const sessionID = cookies.get('session')?.value const sessionID = cookies.get('session')?.value
const bpAuth = pb.authStore
if(!sessionID){ if(!sessionID){
return return null
} }
if(!pb.authStore.isValid){ if(!bpAuth.isValid){
return return null
}
if(!bpAuth){
return null
} }
console.log(pb.authStore.model) console.log(bpAuth.model)
return pb.authStore.model
if(!bpAuth.model){
return null
}
const output: UserObj = {
id: bpAuth.model.id as string,
collectionId: bpAuth.model.collectionId as string,
collectionName: bpAuth.model.collectionName as string,
created: bpAuth.model.created as string,
updated: bpAuth.model.updated as string,
avatar: bpAuth.model.avatar as string,
username: bpAuth.model.username as string,
email: bpAuth.model.email as string,
emailVisibility: false,
name: bpAuth.model.name as string,
password: undefined,
passwordConfirm: undefined,
}
return output
} }
@ -76,7 +101,7 @@ export async function setUser(cookies: AstroCookies, user: UserObj): Promise<voi
httpOnly: true, httpOnly: true,
path: '/', path: '/',
secure: secure, secure: secure,
sameSite: 'Strict', sameSite: 'strict',
maxAge: 365000, maxAge: 365000,
}) })
} }

View File

@ -0,0 +1,27 @@
import PocketBase from 'pocketbase'
import { defineMiddleware } from 'astro/middleware'
import { getEnv } from 'libs/Env'
export const onRequest = defineMiddleware(async ({ locals, request }: any, next: () => any) => {
locals.pb = new PocketBase(getEnv('POCKETBASE_URL','http://localhost:8080'))
// load the store data from the request cookie string
locals.pb.authStore.loadFromCookie(request.headers.get('cookie') || '')
try {
// get an up-to-date auth store state by verifying and refreshing the loaded auth model (if any)
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
locals.pb.authStore.isValid && await locals.pb.collection('users').authRefresh()
} catch (_) {
// clear the auth store on failed refresh
locals.pb.authStore.clear()
}
const response = await next()
// send back the default 'pb_auth' cookie to the client with the latest store state
response.headers.append('set-cookie', locals.pb.authStore.exportToCookie())
return response
})

View File

@ -1,19 +1,19 @@
export interface PBData{ export interface PBData{
id: string | null id?: string | null
collectionId: string | null collectionId?: string | null
collectionName: string | null collectionName?: string | null
created: string | null // TODO: passé ca en date auto created?: string | null // TODO: passé ca en date auto
updated: string | null // TODO: passé ca en date auto updated?: string | null // TODO: passé ca en date auto
} }
export default interface UserObj extends PBData{ export default interface UserObj extends PBData{
avatar: string | null avatar?: string | null
username: string username: string
email: string email: string
emailVisibility: false emailVisibility?: boolean
password: string | null password?: string | undefined
passwordConfirm: string | null passwordConfirm?: string | undefined
name: string | null name: string | null
} }

View File

@ -1,16 +1,18 @@
--- ---
import Layout from 'layouts/Layout.astro'; import Layout from 'layouts/Layout.astro'
import { getUser } from 'libs/AuthUtils'; import PocketBase from 'pocketbase'
const user = await getUser(Astro.cookies); const pb = Astro.locals.pb as PocketBase
const auth = pb.authStore
const user = auth.model
if(!user){ if(!auth.isValid){
return Astro.redirect("/account/login"); return Astro.redirect("/account/login");
} }
--- ---
<Layout title="Account setting"> <Layout title="Account setting">
<h1>Bonjour {user.name}</h1> <h1>Bonjour {user!.name}</h1>
</Layout> </Layout>

View File

@ -1,29 +1,33 @@
--- ---
import Layout from "../../layouts/Layout.astro"; import Layout from "layouts/Layout.astro";
import PocketBase from 'pocketbase'; import AstroUtils from "libs/AstroUtils";
import AstroUtils from "../../libs/AstroUtils"; import PocketBase from 'pocketbase'
import { getUser, login } from "libs/AuthUtils";
const pb = Astro.locals.pb as PocketBase
const usr = await getUser(Astro.cookies) if(pb.authStore.isValid){
if (usr) { return Astro.redirect("/account")
// return Astro.redirect(route('/', {message: 'Vous êtes déjà connecté !'}))
} }
const res = await AstroUtils.wrap(async () => { const res = await AstroUtils.wrap(async () => {
if (Astro.request.method !== 'POST') { if (Astro.request.method !== 'POST') {
return return
} }
// FIXME checké si utilisateur deja connecté
const locals = Astro.locals
const form = await Astro.request.formData(); const form = await Astro.request.formData();
const request = { const request = {
user: form.get("username") as string, user: form.get("username") as string,
password: form.get("password") as string password: form.get("password") as string
} }
try {
await login(Astro.cookies, request) await locals.pb.collection('users').authWithPassword(request.user,request.password);
} catch (error) {
console.log(error)
}
return Astro.redirect("/account") return Astro.redirect("/account")

View File

@ -1,32 +1,33 @@
--- ---
import PocketBase from 'pocketbase'; import Layout from 'layouts/Layout.astro';
import Layout from '../../layouts/Layout.astro'; import AstroUtils from 'libs/AstroUtils';
import AstroUtils from '../../libs/AstroUtils'; import PocketBase from 'pocketbase'
import { getUser, setUser } from 'libs/AuthUtils';
import UserObj from 'models/User';
const connected = await getUser(Astro.cookies)
if(connected) { const pb = Astro.locals.pb as PocketBase
return Astro.redirect(route('/'))
if(pb.authStore.isValid){
return Astro.redirect("/account")
} }
await AstroUtils.wrap(async () => {
const res = await AstroUtils.wrap(async () => {
if (Astro.request.method !== 'POST'){ if (Astro.request.method !== 'POST'){
return return
} }
const form = await Astro.request.formData() const form = await Astro.request.formData()
const request : UserObj = { const request = {
username: form.get("username") as string, username: form.get("username") as string,
name: form.get("name") as string, name: form.get("name") as string,
email: form.get("email") as string, email: form.get("email") as string,
password: form.get("password") as string, password: form.get("password") as string,
passwordConfirm: form.get("passwordConfirm") as string, passwordConfirm: form.get("passwordConfirm") as string,
emailVisibility: false
} }
await setUser(Astro.cookies, request); try{
await pb.collection('users').create(request)
return Astro.redirect('account/login')
}catch(e){
console.log(e);
}
}) })
--- ---

View File

@ -5,4 +5,7 @@
// hide an issue with typescript // hide an issue with typescript
"noUnusedLocals": false "noUnusedLocals": false
}, },
"ts-node": {
"esm": true
}
} }