mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
fix: improve fingerprint generation and project status handling for cloud projects
This commit is contained in:
@@ -4,6 +4,7 @@ const SECRET = env.PUBLIC_CONSOLE_FINGERPRINT_KEY ?? '';
|
||||
const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
|
||||
|
||||
async function sha256(message: string): Promise<string> {
|
||||
if (!crypto?.subtle) return '';
|
||||
const data = new TextEncoder().encode(message);
|
||||
const hash = await crypto.subtle.digest('SHA-256', data);
|
||||
return Array.from(new Uint8Array(hash))
|
||||
@@ -12,6 +13,7 @@ async function sha256(message: string): Promise<string> {
|
||||
}
|
||||
|
||||
async function hmacSha256(message: string, secret: string): Promise<string> {
|
||||
if (!crypto?.subtle) return '';
|
||||
const key = await crypto.subtle.importKey(
|
||||
'raw',
|
||||
new TextEncoder().encode(secret),
|
||||
@@ -204,7 +206,7 @@ export async function generateFingerprintToken(): Promise<string> {
|
||||
};
|
||||
|
||||
const payload = JSON.stringify(signals);
|
||||
const encoded = btoa(payload);
|
||||
const encoded = btoa(unescape(encodeURIComponent(payload)));
|
||||
|
||||
if (!SECRET) {
|
||||
return encoded;
|
||||
|
||||
@@ -13,6 +13,7 @@ import { redirect } from '@sveltejs/kit';
|
||||
import { resolve } from '$app/paths';
|
||||
import { generateFingerprintToken } from '$lib/helpers/fingerprint';
|
||||
import { normalizeConsoleVariables } from '$lib/helpers/domains';
|
||||
import { browser } from '$app/environment';
|
||||
|
||||
export const load: LayoutLoad = async ({ params, depends, parent }) => {
|
||||
const { plansInfo, organizations, preferences: prefs } = await parent();
|
||||
@@ -103,35 +104,24 @@ export const load: LayoutLoad = async ({ params, depends, parent }) => {
|
||||
plansInfo.set(organization.billingPlanId, organizationPlan);
|
||||
}
|
||||
|
||||
// Track console access for cloud only (fire-and-forget, backend has 6-day cooldown)
|
||||
// Don't call if project is paused - user must explicitly resume via createConsoleAccess
|
||||
if (isCloud) {
|
||||
const projectInactivityDays = organizationPlan?.projectInactivityDays ?? 0;
|
||||
const consoleAccessedAt = (project as { consoleAccessedAt?: string }).consoleAccessedAt;
|
||||
|
||||
let isPaused = false;
|
||||
if (projectInactivityDays > 0 && consoleAccessedAt) {
|
||||
const lastAccess = new Date(consoleAccessedAt);
|
||||
const now = new Date();
|
||||
const diffDays = Math.floor(
|
||||
(now.getTime() - lastAccess.getTime()) / (1000 * 60 * 60 * 24)
|
||||
);
|
||||
isPaused = diffDays >= projectInactivityDays;
|
||||
}
|
||||
|
||||
if (!isPaused) {
|
||||
generateFingerprintToken()
|
||||
.then((fingerprint) => {
|
||||
sdk.forConsole.client.headers['X-Appwrite-Console-Fingerprint'] = fingerprint;
|
||||
return sdk.forConsole.projects.updateConsoleAccess({
|
||||
projectId: params.project
|
||||
});
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
delete sdk.forConsole.client.headers['X-Appwrite-Console-Fingerprint'];
|
||||
// Track console access for cloud projects (fire-and-forget, backend has 6-day cooldown).
|
||||
// Skip if paused — user must explicitly resume via the paused project modal.
|
||||
if (isCloud && browser && project.status !== 'paused') {
|
||||
generateFingerprintToken()
|
||||
.then((fingerprint) => {
|
||||
sdk.forConsole.client.headers['X-Appwrite-Console-Fingerprint'] = fingerprint;
|
||||
return (
|
||||
sdk.forConsole.projects as unknown as {
|
||||
updateConsoleAccess(params: { projectId: string }): Promise<unknown>;
|
||||
}
|
||||
).updateConsoleAccess({
|
||||
projectId: params.project
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
delete sdk.forConsole.client.headers['X-Appwrite-Console-Fingerprint'];
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
import { Submit, trackError } from '$lib/actions/analytics';
|
||||
import { generateFingerprintToken } from '$lib/helpers/fingerprint';
|
||||
import { Alert, Layout, Modal, Typography } from '@appwrite.io/pink-svelte';
|
||||
import { Status } from '@appwrite.io/console';
|
||||
|
||||
let {
|
||||
show = $bindable(false),
|
||||
@@ -29,7 +28,14 @@
|
||||
sdk.forConsole.client.headers['X-Appwrite-Console-Fingerprint'] = fingerprint;
|
||||
|
||||
try {
|
||||
await sdk.forConsole.projects.updateStatus({ projectId, status: Status.Active });
|
||||
await (
|
||||
sdk.forConsole.projects as unknown as {
|
||||
updateStatus(params: {
|
||||
projectId: string;
|
||||
status: string;
|
||||
}): Promise<unknown>;
|
||||
}
|
||||
).updateStatus({ projectId, status: 'active' });
|
||||
} finally {
|
||||
delete sdk.forConsole.client.headers['X-Appwrite-Console-Fingerprint'];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user