Compare commits
13 Commits
fix-SSR-wi
...
d8fc85ca5e
Author | SHA1 | Date | |
---|---|---|---|
d8fc85ca5e | |||
ee732dc722 | |||
509a19f0c9 | |||
f863a918bf | |||
56345d9933 | |||
564a18ea28 | |||
362b0e7af7 | |||
f53f19dc93 | |||
9a4357394a | |||
41ed285326 | |||
2b11a223cd | |||
9116a1544e | |||
5f642a6aa0 |
30
bruno/OpenData datatourisme/Google API.bru
Normal file
30
bruno/OpenData datatourisme/Google API.bru
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
meta {
|
||||||
|
name: Google API
|
||||||
|
type: http
|
||||||
|
seq: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
url: https://places.googleapis.com/v1/places:searchNearby
|
||||||
|
body: json
|
||||||
|
auth: none
|
||||||
|
}
|
||||||
|
|
||||||
|
headers {
|
||||||
|
X-Goog-Api-Key: {{GOOGLE_API_KEY}}
|
||||||
|
}
|
||||||
|
|
||||||
|
body:json {
|
||||||
|
{
|
||||||
|
"includedTypes": ["restaurant"],
|
||||||
|
"maxResultCount": 10,
|
||||||
|
"locationRestriction": {
|
||||||
|
"circle": {
|
||||||
|
"center": {
|
||||||
|
"latitude": 37.7937,
|
||||||
|
"longitude": -122.3965},
|
||||||
|
"radius": 500.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
vars:secret [
|
vars:secret [
|
||||||
app_key
|
app_key,
|
||||||
|
GOOGLE_API_KEY
|
||||||
]
|
]
|
||||||
|
11
bruno/OpenData datatourisme/list oaut methode.bru
Normal file
11
bruno/OpenData datatourisme/list oaut methode.bru
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
meta {
|
||||||
|
name: list oaut methode
|
||||||
|
type: http
|
||||||
|
seq: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
get {
|
||||||
|
url: https://pb-tweb.cb85.fr/api/collections/users/auth-methods
|
||||||
|
body: none
|
||||||
|
auth: none
|
||||||
|
}
|
18
bruno/OpenData datatourisme/oauth test.bru
Normal file
18
bruno/OpenData datatourisme/oauth test.bru
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
meta {
|
||||||
|
name: oauth test
|
||||||
|
type: http
|
||||||
|
seq: 4
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
url: https://pb-tweb.cb85.fr/api/collections/users/auth-with-oauth2
|
||||||
|
body: json
|
||||||
|
auth: none
|
||||||
|
}
|
||||||
|
|
||||||
|
body:json {
|
||||||
|
{
|
||||||
|
provider: "google"
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
1479
front/package-lock.json
generated
1479
front/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -24,7 +24,6 @@
|
|||||||
"pocketbase": "^0.21.1",
|
"pocketbase": "^0.21.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"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"
|
"typescript": "^5"
|
||||||
@ -39,6 +38,7 @@
|
|||||||
"@vitest/coverage-v8": "^1",
|
"@vitest/coverage-v8": "^1",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-plugin-astro": "^0.31.4",
|
"eslint-plugin-astro": "^0.31.4",
|
||||||
|
"eslint-plugin-jsx-a11y": "^6.8.0",
|
||||||
"typescript": "^5",
|
"typescript": "^5",
|
||||||
"vitest": "^1"
|
"vitest": "^1"
|
||||||
}
|
}
|
||||||
|
19
front/src/env.d.ts
vendored
19
front/src/env.d.ts
vendored
@ -16,10 +16,17 @@ interface ImportMeta {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
// declare namespace App {
|
||||||
declare namespace App {
|
// interface Locals {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
// pb: PocketBase
|
||||||
export interface Locals {
|
// }
|
||||||
pb: PocketBase
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
namespace App {
|
||||||
|
interface Locals {
|
||||||
|
pb: PocketBase
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,107 +0,0 @@
|
|||||||
import type { AstroCookies } from 'astro'
|
|
||||||
import type UserObj from 'models/User'
|
|
||||||
import PocketBase from 'pocketbase'
|
|
||||||
import { getEnv } from 'libs/Env'
|
|
||||||
|
|
||||||
|
|
||||||
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> {
|
|
||||||
const sessionID = cookies.get('session')?.value
|
|
||||||
|
|
||||||
if(!sessionID){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cookies.delete('session',{
|
|
||||||
path: '/'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function login(cookies: AstroCookies, user: {user: string, password: string}): Promise<boolean> {
|
|
||||||
|
|
||||||
const authData = await pb.collection('users').authWithPassword(user.user, user.password)
|
|
||||||
|
|
||||||
let secure = true
|
|
||||||
|
|
||||||
if (getEnv('NODE_ENV', 'production') !== 'production') {
|
|
||||||
secure = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if(authData){
|
|
||||||
cookies.set('session', authData.token,{
|
|
||||||
httpOnly: true,
|
|
||||||
path: '/',
|
|
||||||
secure: secure,
|
|
||||||
sameSite: 'strict',
|
|
||||||
maxAge: 365000,
|
|
||||||
})
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getUser(cookies: AstroCookies): Promise<UserObj | null> {
|
|
||||||
const sessionID = cookies.get('session')?.value
|
|
||||||
|
|
||||||
const bpAuth = pb.authStore
|
|
||||||
|
|
||||||
if(!sessionID){
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
if(!bpAuth.isValid){
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
if(!bpAuth){
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(bpAuth.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
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function setUser(cookies: AstroCookies, user: UserObj): Promise<void>{
|
|
||||||
|
|
||||||
const record = await pb.collection('users').create(user)
|
|
||||||
|
|
||||||
console.log(record)
|
|
||||||
|
|
||||||
const session = pb.authStore.token
|
|
||||||
|
|
||||||
console.log(session)
|
|
||||||
|
|
||||||
let secure = true
|
|
||||||
|
|
||||||
if (getEnv('NODE_ENV', 'production') !== 'production') {
|
|
||||||
secure = false
|
|
||||||
}
|
|
||||||
|
|
||||||
cookies.set('session', session,{
|
|
||||||
httpOnly: true,
|
|
||||||
path: '/',
|
|
||||||
secure: secure,
|
|
||||||
sameSite: 'strict',
|
|
||||||
maxAge: 365000,
|
|
||||||
})
|
|
||||||
}
|
|
@ -3,11 +3,12 @@ import PocketBase from 'pocketbase'
|
|||||||
import { defineMiddleware } from 'astro/middleware'
|
import { defineMiddleware } from 'astro/middleware'
|
||||||
import { getEnv } from 'libs/Env'
|
import { getEnv } from 'libs/Env'
|
||||||
|
|
||||||
export const onRequest = defineMiddleware(async ({ locals, request }: any, next: () => any) => {
|
export const onRequest = defineMiddleware(async ({ locals, cookies}, next) => {
|
||||||
locals.pb = new PocketBase(getEnv('POCKETBASE_URL','http://localhost:8080'))
|
locals.pb = new PocketBase(getEnv('POCKETBASE_URL','http://localhost:8080'))
|
||||||
|
|
||||||
// load the store data from the request cookie string
|
// load the store data from the request cookie string
|
||||||
locals.pb.authStore.loadFromCookie(request.headers.get('cookie') || '')
|
const pbcookie = cookies.get('session')?.value
|
||||||
|
locals.pb.authStore.loadFromCookie('pb_auth=' + pbcookie || '')
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// get an up-to-date auth store state by verifying and refreshing the loaded auth model (if any)
|
// get an up-to-date auth store state by verifying and refreshing the loaded auth model (if any)
|
||||||
@ -20,8 +21,19 @@ export const onRequest = defineMiddleware(async ({ locals, request }: any, next:
|
|||||||
|
|
||||||
const response = await next()
|
const response = await next()
|
||||||
|
|
||||||
// send back the default 'pb_auth' cookie to the client with the latest store state
|
let secure = true
|
||||||
response.headers.append('set-cookie', locals.pb.authStore.exportToCookie())
|
if (getEnv('NODE_ENV', 'production') !== 'production') {
|
||||||
|
secure = false
|
||||||
|
}
|
||||||
|
const pbcookieStr = locals.pb.authStore.exportToCookie()
|
||||||
|
|
||||||
|
cookies.set('session',pbcookieStr.slice(pbcookieStr.indexOf('=')+1,pbcookieStr.indexOf(';')),{
|
||||||
|
httpOnly: true,
|
||||||
|
path: '/',
|
||||||
|
secure: secure,
|
||||||
|
sameSite: 'lax',
|
||||||
|
maxAge: 365000
|
||||||
|
})
|
||||||
|
|
||||||
return response
|
return response
|
||||||
})
|
})
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
export interface PBData{
|
|
||||||
id?: string | null
|
|
||||||
collectionId?: string | null
|
|
||||||
collectionName?: string | null
|
|
||||||
created?: string | null // TODO: passé ca en date auto
|
|
||||||
updated?: string | null // TODO: passé ca en date auto
|
|
||||||
}
|
|
||||||
|
|
||||||
export default interface UserObj extends PBData{
|
|
||||||
avatar?: string | null
|
|
||||||
username: string
|
|
||||||
email: string
|
|
||||||
emailVisibility?: boolean
|
|
||||||
password?: string | undefined
|
|
||||||
passwordConfirm?: string | undefined
|
|
||||||
name: string | null
|
|
||||||
}
|
|
@ -3,7 +3,7 @@ import Layout from 'layouts/Layout.astro'
|
|||||||
import PocketBase from 'pocketbase'
|
import PocketBase from 'pocketbase'
|
||||||
|
|
||||||
|
|
||||||
const pb = Astro.locals.pb as PocketBase
|
const pb = Astro.locals.pb
|
||||||
const auth = pb.authStore
|
const auth = pb.authStore
|
||||||
const user = auth.model
|
const user = auth.model
|
||||||
|
|
||||||
@ -15,4 +15,7 @@ if(!auth.isValid){
|
|||||||
|
|
||||||
<Layout title="Account setting">
|
<Layout title="Account setting">
|
||||||
<h1>Bonjour {user!.name}</h1>
|
<h1>Bonjour {user!.name}</h1>
|
||||||
|
<div>
|
||||||
|
<a href="/account/logout">deconnexion</a>
|
||||||
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
@ -4,7 +4,7 @@ import AstroUtils from "libs/AstroUtils";
|
|||||||
import PocketBase from 'pocketbase'
|
import PocketBase from 'pocketbase'
|
||||||
|
|
||||||
|
|
||||||
const pb = Astro.locals.pb as PocketBase
|
const pb = Astro.locals.pb
|
||||||
|
|
||||||
if(pb.authStore.isValid){
|
if(pb.authStore.isValid){
|
||||||
return Astro.redirect("/account")
|
return Astro.redirect("/account")
|
||||||
@ -13,10 +13,7 @@ if(pb.authStore.isValid){
|
|||||||
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,
|
||||||
@ -24,13 +21,13 @@ const res = await AstroUtils.wrap(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await locals.pb.collection('users').authWithPassword(request.user,request.password);
|
await pb.collection('users').authWithPassword(request.user,request.password);
|
||||||
|
return Astro.redirect("/account")
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
|
console.warn('user password is incorrect')
|
||||||
|
return Astro.redirect("/account/login");// route('/account/login', {message: 'Compte invalide, valider les identifiants'})) //XXX: comprendre comment le system de route fonctionne
|
||||||
}
|
}
|
||||||
|
|
||||||
return Astro.redirect("/account")
|
|
||||||
|
|
||||||
})
|
})
|
||||||
---
|
---
|
||||||
|
|
||||||
|
13
front/src/pages/account/logout.astro
Normal file
13
front/src/pages/account/logout.astro
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
import PocketBase from 'pocketbase'
|
||||||
|
|
||||||
|
|
||||||
|
const pb = Astro.locals.pb
|
||||||
|
|
||||||
|
if(pb.authStore.isValid){
|
||||||
|
pb.authStore.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
return Astro.redirect('/account/login')
|
||||||
|
|
||||||
|
---
|
97
front/src/pages/account/oauth.astro
Normal file
97
front/src/pages/account/oauth.astro
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
const pb = Astro.locals.pb
|
||||||
|
const redirectUrl = Astro.url.protocol + "//" + Astro.url.host + '/account/oauth';
|
||||||
|
|
||||||
|
console.log(redirectUrl)
|
||||||
|
|
||||||
|
const params = Astro.url.searchParams
|
||||||
|
|
||||||
|
const code = params.get('code')
|
||||||
|
|
||||||
|
console.log(Astro.request.headers.get('cookie'))
|
||||||
|
//TODO socké dans les cookies
|
||||||
|
// load the previously stored provider's data
|
||||||
|
const providerstr = Astro.cookies.get('provider')
|
||||||
|
|
||||||
|
if (!providerstr) {
|
||||||
|
console.error("Fail to load provider")
|
||||||
|
console.log(providerstr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const provider = providerstr.json()
|
||||||
|
|
||||||
|
if (!code) {
|
||||||
|
console.error("Fail to load code params");
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// compare the redirect's state param and the stored provider's one
|
||||||
|
if (provider.state !== params.get('state')) {
|
||||||
|
throw "State parameters don't match.";
|
||||||
|
}
|
||||||
|
|
||||||
|
pb.collection('users').authWithOAuth2Code(
|
||||||
|
provider.name,
|
||||||
|
code,
|
||||||
|
provider.codeVerifier,
|
||||||
|
redirectUrl,
|
||||||
|
// pass optional user create data
|
||||||
|
{
|
||||||
|
emailVisibility: false,
|
||||||
|
}
|
||||||
|
).then((authData) => {
|
||||||
|
//REDIRECT
|
||||||
|
console.log("oauth OK !!");
|
||||||
|
console.log(JSON.stringify(authData, null, 2));
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log("oauth fail !!");
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>OAuth2 redirect page</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre id="content">Authenticating...</pre>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/gh/pocketbase/js-sdk@master/dist/pocketbase.umd.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
const pb = new PocketBase("http://127.0.0.1:8090");
|
||||||
|
const redirectUrl = 'http://127.0.0.1:8090/redirect.html';
|
||||||
|
|
||||||
|
// parse the query parameters from the redirected url
|
||||||
|
const params = (new URL(window.location)).searchParams;
|
||||||
|
|
||||||
|
// load the previously stored provider's data
|
||||||
|
const provider = JSON.parse(localStorage.getItem('provider'))
|
||||||
|
|
||||||
|
// compare the redirect's state param and the stored provider's one
|
||||||
|
if (provider.state !== params.get('state')) {
|
||||||
|
throw "State parameters don't match.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// authenticate
|
||||||
|
pb.collection('users').authWithOAuth2Code(
|
||||||
|
provider.name,
|
||||||
|
params.get('code'),
|
||||||
|
provider.codeVerifier,
|
||||||
|
redirectUrl,
|
||||||
|
// pass optional user create data
|
||||||
|
{
|
||||||
|
emailVisibility: false,
|
||||||
|
}
|
||||||
|
).then((authData) => {
|
||||||
|
document.getElementById('content').innerText = JSON.stringify(authData, null, 2);
|
||||||
|
}).catch((err) => {
|
||||||
|
document.getElementById('content').innerText = "Failed to exchange code.\n" + err;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,10 +1,27 @@
|
|||||||
---
|
---
|
||||||
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 { getEnv } from 'libs/Env';
|
||||||
|
|
||||||
|
const pb = Astro.locals.pb
|
||||||
|
|
||||||
|
const oauths = await pb.collection('users').listAuthMethods();
|
||||||
|
|
||||||
|
|
||||||
const pb = Astro.locals.pb as PocketBase
|
console.log(JSON.stringify(oauths.authProviders[0]));
|
||||||
|
|
||||||
|
let secure = true
|
||||||
|
if (getEnv('NODE_ENV', 'production') !== 'production') {
|
||||||
|
secure = false
|
||||||
|
}
|
||||||
|
|
||||||
|
Astro.cookies.set('provider', oauths.authProviders[0],{
|
||||||
|
httpOnly: true,
|
||||||
|
path: '/',
|
||||||
|
secure: secure,
|
||||||
|
sameSite: 'lax',
|
||||||
|
maxAge: 365000
|
||||||
|
})
|
||||||
|
|
||||||
if(pb.authStore.isValid){
|
if(pb.authStore.isValid){
|
||||||
return Astro.redirect("/account")
|
return Astro.redirect("/account")
|
||||||
@ -15,24 +32,34 @@ await AstroUtils.wrap(async () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
const form = await Astro.request.formData()
|
const form = await Astro.request.formData()
|
||||||
const request = {
|
if(form.get("type") == "userPassword"){
|
||||||
username: form.get("username") as string,
|
const request = {
|
||||||
name: form.get("name") as string,
|
username: form.get("username") as string,
|
||||||
email: form.get("email") as string,
|
name: form.get("name") as string,
|
||||||
password: form.get("password") as string,
|
email: form.get("email") as string,
|
||||||
passwordConfirm: form.get("passwordConfirm") as string,
|
password: form.get("password") as string,
|
||||||
}
|
passwordConfirm: form.get("passwordConfirm") as string,
|
||||||
try{
|
}
|
||||||
await pb.collection('users').create(request)
|
try{
|
||||||
return Astro.redirect('account/login')
|
await pb.collection('users').create(request)
|
||||||
}catch(e){
|
return Astro.redirect('/account/login')
|
||||||
console.log(e);
|
}catch(e){
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
}else if (form.get("type") == "discord2FA") {
|
||||||
|
// console.log("pouet")
|
||||||
|
// await pb.collection('user').authWithOAuth2({provider: 'discord'})
|
||||||
|
// console.log("pouetF");
|
||||||
|
|
||||||
|
}else{
|
||||||
|
Astro.redirect("/404")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="register">
|
<Layout title="register">
|
||||||
<form id="account-creation" method="post" enctype="multipart/form-data">
|
<form id="account-creation" method="post" enctype="multipart/form-data">
|
||||||
|
<input type="hidden" name="type" value="userPassword">
|
||||||
<input required name="name" placeholder="Prénom Nom"/>
|
<input required name="name" placeholder="Prénom Nom"/>
|
||||||
<input required name="username" placeholder="Pseudo"/>
|
<input required name="username" placeholder="Pseudo"/>
|
||||||
<input required name="email" type="email" placeholder="Renseignez votre email" />
|
<input required name="email" type="email" placeholder="Renseignez votre email" />
|
||||||
@ -40,4 +67,11 @@ await AstroUtils.wrap(async () => {
|
|||||||
<input required name="passwordConfirm" type="password" placeholder="Confirmer votre mot de passe" />
|
<input required name="passwordConfirm" type="password" placeholder="Confirmer votre mot de passe" />
|
||||||
<button>Créer un compte</button>
|
<button>Créer un compte</button>
|
||||||
</form>
|
</form>
|
||||||
</Layout>
|
|
||||||
|
<button id="OauthDiscord">connexion avec discord</button>
|
||||||
|
<form method="post" enctype="multipart/form-data">
|
||||||
|
<input type="hidden" name="type" value="discord2FA">
|
||||||
|
</form>
|
||||||
|
<a href={oauths.authProviders[0].authUrl + Astro.url.protocol + "//" + Astro.url.host + '/account/oauth'}>discord?</a>
|
||||||
|
</Layout>
|
||||||
|
|
@ -1,17 +1,26 @@
|
|||||||
---
|
---
|
||||||
import Layout from 'layouts/Layout.astro';
|
import Layout from 'layouts/Layout.astro';
|
||||||
import { Marker, Popup } from 'leaflet';
|
import 'leaflet/dist/leaflet.css'
|
||||||
import { MapContainer } from 'react-leaflet'
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="maps test">
|
<Layout title="maps test">
|
||||||
|
|
||||||
<MapContainer client:load center={[51.505, -0.09]} zoom={13} scrollWheelZoom={false}>
|
<div class="w-52 h-52" id="map" />
|
||||||
<Marker client:load lat={51.505} lng={-0.09}>
|
|
||||||
<Popup client:load>
|
|
||||||
A pretty CSS3 popup. <br /> Easily customizable.
|
|
||||||
</Popup>
|
|
||||||
</Marker>
|
|
||||||
</MapContainer>
|
|
||||||
|
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import L from 'leaflet'
|
||||||
|
|
||||||
|
const map = L.map('map', {
|
||||||
|
center: [50,0],
|
||||||
|
zoom: 13,
|
||||||
|
preferCanvas: true
|
||||||
|
})
|
||||||
|
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||||
|
maxZoom: 19,
|
||||||
|
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||||
|
}).addTo(map);
|
||||||
|
var marker = L.marker([51.5, -0.09]).addTo(map);
|
||||||
|
</script>
|
Reference in New Issue
Block a user