Add permissions
This commit is contained in:
parent
a392841012
commit
41951d7603
|
|
@ -7,7 +7,8 @@ export default function useDatabase()
|
|||
{
|
||||
if(!instance)
|
||||
{
|
||||
const sqlite = new Database(useRuntimeConfig().database);
|
||||
const database = useRuntimeConfig().database;
|
||||
const sqlite = new Database(database);
|
||||
instance = drizzle({ client: sqlite, schema });
|
||||
|
||||
instance.run("PRAGMA journal_mode = WAL;");
|
||||
|
|
|
|||
BIN
db.sqlite-shm
BIN
db.sqlite-shm
Binary file not shown.
BIN
db.sqlite-wal
BIN
db.sqlite-wal
Binary file not shown.
10
db/schema.ts
10
db/schema.ts
|
|
@ -26,10 +26,10 @@ export const userSessionsTable = sqliteTable("user_sessions", {
|
|||
|
||||
export const userPermissionsTable = sqliteTable("user_permissions", {
|
||||
id: int().notNull().references(() => usersTable.id, { onDelete: 'cascade', onUpdate: 'cascade' }),
|
||||
permissions: text().notNull(),
|
||||
permission: text().notNull(),
|
||||
}, (table): SQLiteTableExtraConfig => {
|
||||
return {
|
||||
pk: primaryKey({ columns: [table.id, table.permissions] }),
|
||||
pk: primaryKey({ columns: [table.id, table.permission] }),
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -43,16 +43,16 @@ export const explorerContentTable = sqliteTable("explorer_content", {
|
|||
private: int({ mode: 'boolean' }).default(false),
|
||||
});
|
||||
|
||||
export const usersRelation = relations(usersTable, ({one, many}) => ({
|
||||
export const usersRelation = relations(usersTable, ({ one, many }) => ({
|
||||
data: one(usersDataTable, { fields: [usersTable.id], references: [usersDataTable.id], }),
|
||||
session: many(userSessionsTable),
|
||||
permission: many(userPermissionsTable),
|
||||
content: many(explorerContentTable),
|
||||
}));
|
||||
export const usersDataRelation = relations(usersDataTable, ({one}) => ({
|
||||
export const usersDataRelation = relations(usersDataTable, ({ one }) => ({
|
||||
users: one(usersTable, { fields: [usersDataTable.id], references: [usersTable.id], }),
|
||||
}));
|
||||
export const userSessionsRelation = relations(userSessionsTable, ({one}) => ({
|
||||
export const userSessionsRelation = relations(userSessionsTable, ({ one }) => ({
|
||||
users: one(usersTable, { fields: [userSessionsTable.user_id], references: [usersTable.id], }),
|
||||
}));
|
||||
export const userPermissionsRelation = relations(userPermissionsTable, ({ one }) => ({
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
PRAGMA foreign_keys=OFF;--> statement-breakpoint
|
||||
CREATE TABLE `__new_user_permissions` (
|
||||
`id` integer NOT NULL,
|
||||
`permission` text NOT NULL,
|
||||
PRIMARY KEY(`id`, `permission`),
|
||||
FOREIGN KEY (`id`) REFERENCES `users`(`id`) ON UPDATE cascade ON DELETE cascade
|
||||
);
|
||||
--> statement-breakpoint
|
||||
INSERT INTO `__new_user_permissions`("id", "permission") SELECT "id", "permission" FROM `user_permissions`;--> statement-breakpoint
|
||||
DROP TABLE `user_permissions`;--> statement-breakpoint
|
||||
ALTER TABLE `__new_user_permissions` RENAME TO `user_permissions`;--> statement-breakpoint
|
||||
PRAGMA foreign_keys=ON;
|
||||
|
|
@ -0,0 +1,300 @@
|
|||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"id": "6da7ff20-0db8-4055-a353-bb0ea2fa5e0b",
|
||||
"prevId": "854cab71-b937-4f4f-80b0-cbb09c7b5944",
|
||||
"tables": {
|
||||
"explorer_content": {
|
||||
"name": "explorer_content",
|
||||
"columns": {
|
||||
"path": {
|
||||
"name": "path",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"owner": {
|
||||
"name": "owner",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "blob",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"navigable": {
|
||||
"name": "navigable",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": true
|
||||
},
|
||||
"private": {
|
||||
"name": "private",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"explorer_content_owner_users_id_fk": {
|
||||
"name": "explorer_content_owner_users_id_fk",
|
||||
"tableFrom": "explorer_content",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"owner"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"user_permissions": {
|
||||
"name": "user_permissions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"permission": {
|
||||
"name": "permission",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_permissions_id_users_id_fk": {
|
||||
"name": "user_permissions_id_users_id_fk",
|
||||
"tableFrom": "user_permissions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_permissions_id_permission_pk": {
|
||||
"columns": [
|
||||
"id",
|
||||
"permission"
|
||||
],
|
||||
"name": "user_permissions_id_permission_pk"
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"user_sessions": {
|
||||
"name": "user_sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"timestamp": {
|
||||
"name": "timestamp",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_sessions_user_id_users_id_fk": {
|
||||
"name": "user_sessions_user_id_users_id_fk",
|
||||
"tableFrom": "user_sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_sessions_id_user_id_pk": {
|
||||
"columns": [
|
||||
"id",
|
||||
"user_id"
|
||||
],
|
||||
"name": "user_sessions_id_user_id_pk"
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"users_data": {
|
||||
"name": "users_data",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"signin": {
|
||||
"name": "signin",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"users_data_id_users_id_fk": {
|
||||
"name": "users_data_id_users_id_fk",
|
||||
"tableFrom": "users_data",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"username": {
|
||||
"name": "username",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"hash": {
|
||||
"name": "hash",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"state": {
|
||||
"name": "state",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": 0
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"users_username_unique": {
|
||||
"name": "users_username_unique",
|
||||
"columns": [
|
||||
"username"
|
||||
],
|
||||
"isUnique": true
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
],
|
||||
"isUnique": true
|
||||
},
|
||||
"users_hash_unique": {
|
||||
"name": "users_hash_unique",
|
||||
"columns": [
|
||||
"hash"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"enums": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {
|
||||
"\"user_permissions\".\"permissions\"": "\"user_permissions\".\"permission\""
|
||||
}
|
||||
},
|
||||
"internal": {
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,13 @@
|
|||
"when": 1730832678255,
|
||||
"tag": "0001_sticky_jack_flag",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 2,
|
||||
"version": "6",
|
||||
"when": 1730985155814,
|
||||
"tag": "0002_messy_solo",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import { relations } from "drizzle-orm/relations";
|
||||
import { users, explorerContent, userSessions, usersData, userPermissions } from "./schema";
|
||||
|
||||
export const explorerContentRelations = relations(explorerContent, ({one}) => ({
|
||||
user: one(users, {
|
||||
fields: [explorerContent.owner],
|
||||
references: [users.id]
|
||||
}),
|
||||
}));
|
||||
|
||||
export const usersRelations = relations(users, ({many}) => ({
|
||||
explorerContents: many(explorerContent),
|
||||
userSessions: many(userSessions),
|
||||
usersData: many(usersData),
|
||||
userPermissions: many(userPermissions),
|
||||
}));
|
||||
|
||||
export const userSessionsRelations = relations(userSessions, ({one}) => ({
|
||||
user: one(users, {
|
||||
fields: [userSessions.userId],
|
||||
references: [users.id]
|
||||
}),
|
||||
}));
|
||||
|
||||
export const usersDataRelations = relations(usersData, ({one}) => ({
|
||||
user: one(users, {
|
||||
fields: [usersData.id],
|
||||
references: [users.id]
|
||||
}),
|
||||
}));
|
||||
|
||||
export const userPermissionsRelations = relations(userPermissions, ({one}) => ({
|
||||
user: one(users, {
|
||||
fields: [userPermissions.id],
|
||||
references: [users.id]
|
||||
}),
|
||||
}));
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
import { sqliteTable, AnySQLiteColumn, foreignKey, text, integer, blob, primaryKey, uniqueIndex } from "drizzle-orm/sqlite-core"
|
||||
import { sql } from "drizzle-orm"
|
||||
|
||||
export const explorerContent = sqliteTable("explorer_content", {
|
||||
path: text().primaryKey().notNull(),
|
||||
owner: integer().notNull().references(() => users.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
title: text().notNull(),
|
||||
type: text().notNull(),
|
||||
content: blob(),
|
||||
navigable: integer().default(true),
|
||||
private: integer().default(false),
|
||||
});
|
||||
|
||||
export const userSessions = sqliteTable("user_sessions", {
|
||||
id: integer().notNull(),
|
||||
userId: integer("user_id").notNull().references(() => users.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
timestamp: integer().notNull(),
|
||||
},
|
||||
(table) => {
|
||||
return {
|
||||
pk0: primaryKey({ columns: [table.id, table.userId], name: "user_sessions_id_user_id_pk"})
|
||||
}
|
||||
});
|
||||
|
||||
export const usersData = sqliteTable("users_data", {
|
||||
id: integer().primaryKey().notNull().references(() => users.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
signin: integer().notNull(),
|
||||
});
|
||||
|
||||
export const users = sqliteTable("users", {
|
||||
id: integer().primaryKey({ autoIncrement: true }).notNull(),
|
||||
username: text().notNull(),
|
||||
email: text().notNull(),
|
||||
hash: text().notNull(),
|
||||
state: integer().default(0).notNull(),
|
||||
},
|
||||
(table) => {
|
||||
return {
|
||||
hashUnique: uniqueIndex("users_hash_unique").on(table.hash),
|
||||
emailUnique: uniqueIndex("users_email_unique").on(table.email),
|
||||
usernameUnique: uniqueIndex("users_username_unique").on(table.username),
|
||||
}
|
||||
});
|
||||
|
||||
export const userPermissions = sqliteTable("user_permissions", {
|
||||
id: integer().notNull().references(() => users.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
permissions: text().notNull(),
|
||||
},
|
||||
(table) => {
|
||||
return {
|
||||
pk0: primaryKey({ columns: [table.id, table.permissions], name: "user_permissions_id_permissions_pk"})
|
||||
}
|
||||
});
|
||||
|
||||
export const drizzleMigrations = sqliteTable("__drizzle_migrations", {
|
||||
});
|
||||
|
||||
|
|
@ -1,9 +1,8 @@
|
|||
export default defineNuxtRouteMiddleware(async (to, from) => {
|
||||
const { loggedIn, ready, fetch } = useUserSession();
|
||||
const { loggedIn, fetch, user } = useUserSession();
|
||||
const meta = to.meta;
|
||||
|
||||
if(!ready)
|
||||
await fetch();
|
||||
await fetch();
|
||||
|
||||
if(!!meta.guestsGoesTo && !loggedIn.value)
|
||||
{
|
||||
|
|
@ -11,12 +10,40 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
|
|||
}
|
||||
else if(meta.requireAuth && !loggedIn.value)
|
||||
{
|
||||
return abortNavigation();
|
||||
return abortNavigation({ statusCode: 401, message: 'Unauthorized', });
|
||||
}
|
||||
else if(!!meta.usersGoesTo && loggedIn.value)
|
||||
{
|
||||
return navigateTo(meta.usersGoesTo);
|
||||
}
|
||||
else if(!!meta.validState && (!loggedIn.value || (user.value?.state ?? 0) === 0))
|
||||
{
|
||||
return abortNavigation({ statusCode: 401, message: 'Unauthorized', });
|
||||
}
|
||||
else if(!!meta.rights)
|
||||
{
|
||||
if(!user.value)
|
||||
{
|
||||
return abortNavigation({ statusCode: 401, message: 'Unauthorized', });
|
||||
}
|
||||
else
|
||||
{
|
||||
let valid = false;
|
||||
for(let i = 0; i < meta.rights.length; i++)
|
||||
{
|
||||
const list = meta.rights[i].split(' ');
|
||||
|
||||
if(list.every(e => user.value.permissions.includes(e)))
|
||||
{
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!valid)
|
||||
return abortNavigation({ statusCode: 401, message: 'Unauthorized', });
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
});
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
"@nuxtjs/tailwindcss": "^6.12.2",
|
||||
"@vueuse/nuxt": "^11.1.0",
|
||||
"drizzle-orm": "^0.35.3",
|
||||
"nuxt": "^3.13.2",
|
||||
"nuxt": "^3.14.159",
|
||||
"nuxt-security": "^2.0.0",
|
||||
"radix-vue": "^1.9.8",
|
||||
"vue": "latest",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
rights: ['admin'],
|
||||
})
|
||||
const job = ref<string>('');
|
||||
|
||||
const toaster = useToast();
|
||||
const data = ref(), status = ref<'idle' | 'pending' | 'success' | 'error'>('idle'), success = ref(false), err = ref(false), error = ref();
|
||||
async function fetch()
|
||||
{
|
||||
|
|
@ -19,6 +23,8 @@ async function fetch()
|
|||
error.value = null;
|
||||
err.value = false;
|
||||
success.value = true;
|
||||
|
||||
toaster.add({ duration: 10000, content: data.value ?? 'Job executé avec succès', type: 'success', timer: true, });
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
|
|
@ -26,6 +32,8 @@ async function fetch()
|
|||
error.value = e;
|
||||
err.value = true;
|
||||
success.value = false;
|
||||
|
||||
toaster.add({ duration: 10000, content: error.value, type: 'error', timer: true, });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ let { user, clear } = useUserSession();
|
|||
<Head>
|
||||
<Title>Mon profil</Title>
|
||||
</Head>
|
||||
<div class="flex w-full items-start py-8 gap-6" v-if="user">
|
||||
<div class="flex gap-4 min-w-1/3 max-w-2/3 border border-light-35 dark:border-dark-35 p-4">
|
||||
<div class="grid grid-cols-4 w-full items-start py-8 gap-6 content-start" v-if="user">
|
||||
<div class="flex gap-4 col-span-3 border border-light-35 dark:border-dark-35 p-4">
|
||||
<Avatar icon="radix-icons:person" :src="`/users/${user?.id}.medium.jpg`" class="w-32 h-32" />
|
||||
<div class="flex flex-col items-start">
|
||||
<ProseH5>{{ user.username }}</ProseH5>
|
||||
|
|
@ -24,5 +24,19 @@ let { user, clear } = useUserSession();
|
|||
<div class="flex-1">
|
||||
<Button @click="async () => await clear()">Se deconnecter</Button>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<ProseTable class="!m-0">
|
||||
<ProseThead>
|
||||
<ProseTr>
|
||||
<ProseTh>Permission</ProseTh>
|
||||
</ProseTr>
|
||||
</ProseThead>
|
||||
<ProseTbody>
|
||||
<ProseTr v-for="permission in user.permissions">
|
||||
<ProseTd>{{ permission }}</ProseTd>
|
||||
</ProseTr>
|
||||
</ProseTbody>
|
||||
</ProseTable>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -73,6 +73,7 @@ export default defineEventHandler(async (e): Promise<Return> => {
|
|||
},
|
||||
with: {
|
||||
data: true,
|
||||
permission: true,
|
||||
},
|
||||
where: (table) => eq(table.id, sql.placeholder('id'))
|
||||
}).prepare().get({ id: id.id });
|
||||
|
|
@ -89,6 +90,7 @@ export default defineEventHandler(async (e): Promise<Return> => {
|
|||
email: user.email,
|
||||
username: user.username,
|
||||
state: user.state,
|
||||
permissions: user.permission.map(e => e.permission),
|
||||
}
|
||||
}) as UserSessionRequired);
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ export default defineEventHandler(async (e): Promise<Return> => {
|
|||
|
||||
db.insert(usersDataTable).values({ id: sql.placeholder('id') }).prepare().run({ id: id.id });
|
||||
|
||||
logSession(e, await setUserSession(e, { user: { id: id.id, username: body.data.username, email: body.data.email, state: 0, signin: new Date() } }) as UserSessionRequired);
|
||||
logSession(e, await setUserSession(e, { user: { id: id.id, username: body.data.username, email: body.data.email, state: 0, signin: new Date(), permissions: [] } }) as UserSessionRequired);
|
||||
|
||||
setResponseStatus(e, 201);
|
||||
return { success: true, session };
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import useDatabase from "~/composables/useDatabase";
|
||||
import { userSessionsTable } from "~/db/schema";
|
||||
import { eq, and, sql } from "drizzle-orm";
|
||||
import { refreshSessionFromDB } from "../utils/user";
|
||||
|
||||
const monthAsMs = 60 * 60 * 24 * 30 * 1000;
|
||||
|
||||
|
|
@ -25,6 +26,7 @@ export default defineNitroPlugin(() => {
|
|||
await db.update(userSessionsTable).set({
|
||||
timestamp: new Date(),
|
||||
}).where(and(eq(userSessionsTable.id, sql.placeholder('id')), eq(userSessionsTable.user_id, sql.placeholder('user_id')))).prepare().run({ id: session.id, user_id: session.user.id });
|
||||
await refreshSessionFromDB(event, session.id);
|
||||
}
|
||||
});
|
||||
sessionHooks.hook('clear', async (session, event) => {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,43 @@ export function logSession(e: H3Event<EventRequestHandler>, session: UserSession
|
|||
{
|
||||
const db = useDatabase();
|
||||
|
||||
console.log("Logging session %s", session.id)
|
||||
db.insert(userSessionsTable).values({ id: sql.placeholder('id'), user_id: sql.placeholder('user_id'), timestamp: sql.placeholder('timestamp') }).prepare().run({ id: session.id, user_id: session.user.id, timestamp: new Date() });
|
||||
return session;
|
||||
}
|
||||
export async function refreshSessionFromDB(e: H3Event<EventRequestHandler>, sessionId: string): Promise<void>
|
||||
{
|
||||
const db = useDatabase();
|
||||
|
||||
const user = db.query.userSessionsTable.findFirst({
|
||||
columns: {
|
||||
id: false,
|
||||
},
|
||||
with: {
|
||||
users: {
|
||||
with: {
|
||||
permission: true,
|
||||
data: true,
|
||||
}
|
||||
}
|
||||
},
|
||||
where: (table) => eq(table.id, sql.placeholder('id'))
|
||||
}).prepare().get({ id: sessionId });
|
||||
|
||||
if(user)
|
||||
{
|
||||
await replaceUserSession(e, {
|
||||
id: sessionId,
|
||||
user: {
|
||||
...user.users.data,
|
||||
email: user.users.email,
|
||||
username: user.users.username,
|
||||
state: user.users.state,
|
||||
permissions: user.users.permission.map(e => e.permission),
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
throw createError({ statusCode: 401, message: 'Invalid session' });
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,8 @@ declare module 'vue-router'
|
|||
requiresAuth?: boolean;
|
||||
guestsGoesTo?: string;
|
||||
usersGoesTo?: string;
|
||||
rights?: string[];
|
||||
validState?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -31,7 +33,9 @@ export interface UserExtendedData {
|
|||
signin: Date;
|
||||
}
|
||||
|
||||
export type User = UserRawData & UserExtendedData;
|
||||
export type Permissions = { permissions: string[] };
|
||||
|
||||
export type User = UserRawData & UserExtendedData & Permissions;
|
||||
|
||||
export interface UserSession {
|
||||
user?: User;
|
||||
|
|
|
|||
Loading…
Reference in New Issue