mirror of
https://github.com/nikdoof/pocket-id.git
synced 2025-12-22 13:59:24 +00:00
feat: add audit log with email notification (#26)
This commit is contained in:
@@ -9,12 +9,16 @@
|
||||
input = $bindable(),
|
||||
label,
|
||||
description,
|
||||
disabled = false,
|
||||
type = 'text',
|
||||
children,
|
||||
...restProps
|
||||
}: HTMLAttributes<HTMLDivElement> & {
|
||||
input?: FormInput<string | boolean | number>;
|
||||
label: string;
|
||||
description?: string;
|
||||
disabled?: boolean;
|
||||
type?: 'text' | 'password' | 'email' | 'number' | 'checkbox';
|
||||
children?: Snippet;
|
||||
} = $props();
|
||||
|
||||
@@ -30,7 +34,7 @@
|
||||
{#if children}
|
||||
{@render children()}
|
||||
{:else if input}
|
||||
<Input {id} bind:value={input.value} />
|
||||
<Input {id} {type} bind:value={input.value} {disabled} />
|
||||
{/if}
|
||||
{#if input?.error}
|
||||
<p class="mt-1 text-sm text-red-500">{input.error}</p>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import applicationConfigurationStore from '$lib/stores/application-configuration-store';
|
||||
import appConfigStore from '$lib/stores/application-configuration-store';
|
||||
import userStore from '$lib/stores/user-store';
|
||||
import Logo from '../logo.svelte';
|
||||
import HeaderAvatar from './header-avatar.svelte';
|
||||
@@ -17,7 +17,7 @@
|
||||
{#if !isAuthPage}
|
||||
<Logo class="mr-3 h-10 w-10" />
|
||||
<h1 class="text-lg font-medium" data-testid="application-name">
|
||||
{$applicationConfigurationStore.appName}
|
||||
{$appConfigStore.appName}
|
||||
</h1>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
<tr
|
||||
class={cn(
|
||||
"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
|
||||
"border-b transition-colors data-[state=selected]:bg-muted",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
import type {
|
||||
AllApplicationConfiguration,
|
||||
ApplicationConfigurationRawResponse
|
||||
AllAppConfig,
|
||||
AppConfigRawResponse
|
||||
} from '$lib/types/application-configuration';
|
||||
import APIService from './api-service';
|
||||
|
||||
export default class ApplicationConfigurationService extends APIService {
|
||||
export default class AppConfigService extends APIService {
|
||||
async list(showAll = false) {
|
||||
let url = '/application-configuration';
|
||||
if (showAll) {
|
||||
url += '/all';
|
||||
}
|
||||
|
||||
const { data } = await this.api.get<ApplicationConfigurationRawResponse>(url);
|
||||
const { data } = await this.api.get<AppConfigRawResponse>(url);
|
||||
|
||||
const applicationConfiguration: Partial<AllApplicationConfiguration> = {};
|
||||
const appConfig: Partial<AllAppConfig> = {};
|
||||
data.forEach(({ key, value }) => {
|
||||
(applicationConfiguration as any)[key] = value;
|
||||
(appConfig as any)[key] = value;
|
||||
});
|
||||
|
||||
return applicationConfiguration as AllApplicationConfiguration;
|
||||
return appConfig as AllAppConfig;
|
||||
}
|
||||
|
||||
async update(applicationConfiguration: AllApplicationConfiguration) {
|
||||
const res = await this.api.put('/application-configuration', applicationConfiguration);
|
||||
return res.data as AllApplicationConfiguration;
|
||||
async update(appConfig: AllAppConfig) {
|
||||
const res = await this.api.put('/application-configuration', appConfig);
|
||||
return res.data as AllAppConfig;
|
||||
}
|
||||
|
||||
async updateFavicon(favicon: File) {
|
||||
20
frontend/src/lib/services/audit-log-service.ts
Normal file
20
frontend/src/lib/services/audit-log-service.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import type { AuditLog } from '$lib/types/audit-log.type';
|
||||
import type { Paginated, PaginationRequest } from '$lib/types/pagination.type';
|
||||
import APIService from './api-service';
|
||||
|
||||
class AuditLogService extends APIService {
|
||||
async list(pagination?: PaginationRequest) {
|
||||
const page = pagination?.page || 1;
|
||||
const limit = pagination?.limit || 10;
|
||||
|
||||
const res = await this.api.get('/audit-logs', {
|
||||
params: {
|
||||
page,
|
||||
limit
|
||||
}
|
||||
});
|
||||
return res.data as Paginated<AuditLog>;
|
||||
}
|
||||
}
|
||||
|
||||
export default AuditLogService;
|
||||
@@ -1,22 +1,22 @@
|
||||
import ApplicationConfigurationService from '$lib/services/application-configuration-service';
|
||||
import type { ApplicationConfiguration } from '$lib/types/application-configuration';
|
||||
import AppConfigService from '$lib/services/app-config-service';
|
||||
import type { AppConfig } from '$lib/types/application-configuration';
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
const applicationConfigurationStore = writable<ApplicationConfiguration>();
|
||||
const appConfigStore = writable<AppConfig>();
|
||||
|
||||
const applicationConfigurationService = new ApplicationConfigurationService();
|
||||
const appConfigService = new AppConfigService();
|
||||
|
||||
const reload = async () => {
|
||||
const applicationConfiguration = await applicationConfigurationService.list();
|
||||
applicationConfigurationStore.set(applicationConfiguration);
|
||||
const appConfig = await appConfigService.list();
|
||||
appConfigStore.set(appConfig);
|
||||
};
|
||||
|
||||
const set = (applicationConfiguration: ApplicationConfiguration) => {
|
||||
applicationConfigurationStore.set(applicationConfiguration);
|
||||
}
|
||||
const set = (appConfig: AppConfig) => {
|
||||
appConfigStore.set(appConfig);
|
||||
};
|
||||
|
||||
export default {
|
||||
subscribe: applicationConfigurationStore.subscribe,
|
||||
subscribe: appConfigStore.subscribe,
|
||||
reload,
|
||||
set
|
||||
};
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
|
||||
export type AllApplicationConfiguration = {
|
||||
export type AllAppConfig = {
|
||||
appName: string;
|
||||
sessionDuration: string;
|
||||
sessionDuration: string;
|
||||
emailEnabled: string;
|
||||
smtpHost: string;
|
||||
smtpPort: string;
|
||||
smtpFrom: string;
|
||||
smtpUser: string;
|
||||
smtpPassword: string;
|
||||
};
|
||||
|
||||
export type ApplicationConfiguration = AllApplicationConfiguration;
|
||||
export type AppConfig = AllAppConfig;
|
||||
|
||||
export type ApplicationConfigurationRawResponse = {
|
||||
export type AppConfigRawResponse = {
|
||||
key: string;
|
||||
type: string;
|
||||
value: string;
|
||||
}[];
|
||||
type: string;
|
||||
value: string;
|
||||
}[];
|
||||
|
||||
8
frontend/src/lib/types/audit-log.type.ts
Normal file
8
frontend/src/lib/types/audit-log.type.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export type AuditLog = {
|
||||
id: string;
|
||||
event: string;
|
||||
ipAddress: string;
|
||||
device: string;
|
||||
createdAt: string;
|
||||
data: any;
|
||||
};
|
||||
Reference in New Issue
Block a user