diff --git a/apps/api/drizzle-do/0008_sync_access_revocations.sql b/apps/api/drizzle-do/0008_sync_access_revocations.sql
new file mode 100644
index 00000000..97ea53cb
--- /dev/null
+++ b/apps/api/drizzle-do/0008_sync_access_revocations.sql
@@ -0,0 +1,7 @@
+CREATE TABLE `sync_access_revocations` (
+ `key` text PRIMARY KEY NOT NULL,
+ `minimum_version` integer,
+ `expires_at` integer NOT NULL
+);
+--> statement-breakpoint
+DELETE FROM `maintenance_jobs` WHERE `key` = 'sharing_access';
diff --git a/apps/api/drizzle-do/meta/0008_snapshot.json b/apps/api/drizzle-do/meta/0008_snapshot.json
new file mode 100644
index 00000000..1cc698ba
--- /dev/null
+++ b/apps/api/drizzle-do/meta/0008_snapshot.json
@@ -0,0 +1,526 @@
+{
+ "version": "6",
+ "dialect": "sqlite",
+ "id": "8f3505f2-c1af-44b4-86b9-fd9f091b39f5",
+ "prevId": "64bf5baf-ff70-43eb-8310-fe4d564e865d",
+ "tables": {
+ "blobs": {
+ "name": "blobs",
+ "columns": {
+ "blob_id": {
+ "name": "blob_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "size_bytes": {
+ "name": "size_bytes",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "last_uploaded_at": {
+ "name": "last_uploaded_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "delete_after": {
+ "name": "delete_after",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "idx_blobs_state_delete_after": {
+ "name": "idx_blobs_state_delete_after",
+ "columns": [
+ "state",
+ "delete_after"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "coordinator_state": {
+ "name": "coordinator_state",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "vault_id": {
+ "name": "vault_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "current_cursor": {
+ "name": "current_cursor",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "storage_used_bytes": {
+ "name": "storage_used_bytes",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "storage_limit_bytes": {
+ "name": "storage_limit_bytes",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "max_file_size_bytes": {
+ "name": "max_file_size_bytes",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "version_history_retention_days": {
+ "name": "version_history_retention_days",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 1
+ },
+ "last_commit_at": {
+ "name": "last_commit_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "last_gc_at": {
+ "name": "last_gc_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "sync_paused_at": {
+ "name": "sync_paused_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "sync_pause_reason": {
+ "name": "sync_pause_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "entries": {
+ "name": "entries",
+ "columns": {
+ "entry_id": {
+ "name": "entry_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "blob_id": {
+ "name": "blob_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "encrypted_metadata": {
+ "name": "encrypted_metadata",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "deleted": {
+ "name": "deleted",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "updated_seq": {
+ "name": "updated_seq",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "updated_by_user_id": {
+ "name": "updated_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "updated_by_local_vault_id": {
+ "name": "updated_by_local_vault_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "last_mutation_id": {
+ "name": "last_mutation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "idx_entries_updated_seq_entry_id": {
+ "name": "idx_entries_updated_seq_entry_id",
+ "columns": [
+ "updated_seq",
+ "entry_id"
+ ],
+ "isUnique": false
+ },
+ "idx_entries_blob_id": {
+ "name": "idx_entries_blob_id",
+ "columns": [
+ "blob_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "entry_versions": {
+ "name": "entry_versions",
+ "columns": {
+ "version_id": {
+ "name": "version_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "entry_id": {
+ "name": "entry_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "source_revision": {
+ "name": "source_revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "op_type": {
+ "name": "op_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "blob_id": {
+ "name": "blob_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "encrypted_metadata": {
+ "name": "encrypted_metadata",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "bucket_start_ms": {
+ "name": "bucket_start_ms",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "captured_at": {
+ "name": "captured_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_by_local_vault_id": {
+ "name": "created_by_local_vault_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "idx_entry_versions_entry_captured_at": {
+ "name": "idx_entry_versions_entry_captured_at",
+ "columns": [
+ "entry_id",
+ "captured_at",
+ "version_id"
+ ],
+ "isUnique": false
+ },
+ "idx_entry_versions_auto_bucket": {
+ "name": "idx_entry_versions_auto_bucket",
+ "columns": [
+ "entry_id",
+ "reason",
+ "bucket_start_ms"
+ ],
+ "isUnique": true
+ },
+ "idx_entry_versions_expires_at": {
+ "name": "idx_entry_versions_expires_at",
+ "columns": [
+ "expires_at"
+ ],
+ "isUnique": false
+ },
+ "idx_entry_versions_blob_expires_at": {
+ "name": "idx_entry_versions_blob_expires_at",
+ "columns": [
+ "blob_id",
+ "expires_at"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "local_vault_connections": {
+ "name": "local_vault_connections",
+ "columns": {
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "local_vault_id": {
+ "name": "local_vault_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "last_connected_at": {
+ "name": "last_connected_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "local_vault_connections_user_id_local_vault_id_pk": {
+ "columns": [
+ "user_id",
+ "local_vault_id"
+ ],
+ "name": "local_vault_connections_user_id_local_vault_id_pk"
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "maintenance_jobs": {
+ "name": "maintenance_jobs",
+ "columns": {
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "due_at": {
+ "name": "due_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "retry_count": {
+ "name": "retry_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "last_error_at": {
+ "name": "last_error_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "idx_maintenance_jobs_due_at": {
+ "name": "idx_maintenance_jobs_due_at",
+ "columns": [
+ "due_at"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "sync_access_revocations": {
+ "name": "sync_access_revocations",
+ "columns": {
+ "minimum_version": {
+ "name": "minimum_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ }
+ },
+ "views": {},
+ "enums": {},
+ "_meta": {
+ "schemas": {},
+ "tables": {},
+ "columns": {}
+ },
+ "internal": {
+ "indexes": {}
+ }
+}
diff --git a/apps/api/drizzle-do/meta/_journal.json b/apps/api/drizzle-do/meta/_journal.json
index 3d6896c5..e766e6e8 100644
--- a/apps/api/drizzle-do/meta/_journal.json
+++ b/apps/api/drizzle-do/meta/_journal.json
@@ -57,6 +57,13 @@
"when": 1786857725150,
"tag": "0007_aberrant_logan",
"breakpoints": true
+ },
+ {
+ "idx": 8,
+ "version": "6",
+ "when": 1790557279952,
+ "tag": "0008_sync_access_revocations",
+ "breakpoints": true
}
]
}
\ No newline at end of file
diff --git a/apps/api/drizzle-do/migrations.js b/apps/api/drizzle-do/migrations.js
index 3dc5bc02..8943d735 100644
--- a/apps/api/drizzle-do/migrations.js
+++ b/apps/api/drizzle-do/migrations.js
@@ -7,6 +7,7 @@ import m0004 from './0004_broad_jack_power.sql';
import m0005 from './0005_clever_killer_shrike.sql';
import m0006 from './0006_jazzy_rage.sql';
import m0007 from './0007_aberrant_logan.sql';
+import m0008 from './0008_sync_access_revocations.sql';
export default {
journal,
@@ -18,7 +19,8 @@ m0003,
m0004,
m0005,
m0006,
-m0007
+m0007,
+m0008
}
}
\ No newline at end of file
diff --git a/apps/api/drizzle/0007_plus_sharing.sql b/apps/api/drizzle/0007_plus_sharing.sql
new file mode 100644
index 00000000..95c033d6
--- /dev/null
+++ b/apps/api/drizzle/0007_plus_sharing.sql
@@ -0,0 +1,73 @@
+CREATE TABLE `invitation_vault` (
+ `invitation_id` text NOT NULL,
+ `vault_id` text NOT NULL,
+ PRIMARY KEY(`invitation_id`, `vault_id`),
+ FOREIGN KEY (`invitation_id`) REFERENCES `invitation`(`id`) ON UPDATE no action ON DELETE cascade,
+ FOREIGN KEY (`vault_id`) REFERENCES `vault`(`id`) ON UPDATE no action ON DELETE cascade
+);
+--> statement-breakpoint
+CREATE TABLE `sharing_audit` (
+ `id` text PRIMARY KEY NOT NULL,
+ `organization_id` text NOT NULL,
+ `actor_id` text NOT NULL,
+ `action` text NOT NULL,
+ `target_id` text NOT NULL,
+ `created_at` integer NOT NULL,
+ FOREIGN KEY (`organization_id`) REFERENCES `organization`(`id`) ON UPDATE no action ON DELETE cascade
+);
+--> statement-breakpoint
+CREATE INDEX `sharing_audit_org_idx` ON `sharing_audit` (`organization_id`,`created_at`);--> statement-breakpoint
+CREATE TABLE `sharing_refresh` (
+ `vault_id` text PRIMARY KEY NOT NULL,
+ `revision` text NOT NULL,
+ `created_at` integer NOT NULL,
+ FOREIGN KEY (`vault_id`) REFERENCES `vault`(`id`) ON UPDATE no action ON DELETE cascade
+);
+--> statement-breakpoint
+CREATE TABLE `vault_key_request` (
+ `id` text PRIMARY KEY NOT NULL,
+ `vault_id` text NOT NULL,
+ `user_id` text NOT NULL,
+ `purpose` text NOT NULL,
+ `access_version` integer NOT NULL,
+ `public_key` text NOT NULL,
+ `status` text NOT NULL,
+ `envelope_json` text,
+ `approved_by` text,
+ `created_at` integer NOT NULL,
+ `expires_at` integer NOT NULL,
+ FOREIGN KEY (`vault_id`) REFERENCES `vault`(`id`) ON UPDATE no action ON DELETE cascade,
+ FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade,
+ FOREIGN KEY (`approved_by`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE no action
+);
+--> statement-breakpoint
+CREATE INDEX `vault_key_request_vault_status_idx` ON `vault_key_request` (`vault_id`,`status`);--> statement-breakpoint
+CREATE INDEX `vault_key_request_user_idx` ON `vault_key_request` (`user_id`);--> statement-breakpoint
+ALTER TABLE `vault` ADD `shared_at` integer;--> statement-breakpoint
+ALTER TABLE `vault_membership` ADD `access_version` integer DEFAULT 1 NOT NULL;
+--> statement-breakpoint
+ALTER TABLE `vault_membership` ADD `explicit_access` integer DEFAULT true NOT NULL;
+--> statement-breakpoint
+ALTER TABLE `vault_membership` ADD `is_creator` integer DEFAULT false NOT NULL;
+--> statement-breakpoint
+UPDATE vault_membership SET is_creator = (role = 'owner');
+--> statement-breakpoint
+ALTER TABLE `vault_membership` DROP COLUMN `role`;
+--> statement-breakpoint
+-- Preserve legacy shared-password access for existing active users before disabling
+-- the unscoped wrapper fallback on shared vaults. No key is decrypted or rotated.
+INSERT INTO vault_key_wrapper (id, vault_id, key_version, kind, user_id, envelope_json, created_at, revoked_at)
+SELECT lower(hex(randomblob(16))), w.vault_id, w.key_version, 'password', m.user_id, w.envelope_json, w.created_at, NULL
+FROM vault_key_wrapper w
+JOIN vault v ON v.id = w.vault_id AND v.active_key_version = w.key_version
+JOIN vault_membership m ON m.vault_id = w.vault_id AND m.status = 'active'
+JOIN member om ON om.organization_id = v.organization_id AND om.user_id = m.user_id
+WHERE w.kind = 'password' AND w.user_id IS NULL AND w.revoked_at IS NULL
+AND w.id = (SELECT old.id FROM vault_key_wrapper old
+ WHERE old.vault_id = w.vault_id AND old.kind = 'password' AND old.user_id IS NULL
+ AND old.revoked_at IS NULL AND old.key_version = v.active_key_version
+ ORDER BY old.created_at DESC, old.id DESC LIMIT 1)
+ON CONFLICT (vault_id, kind, user_id) DO NOTHING;
+--> statement-breakpoint
+UPDATE vault SET shared_at = created_at
+WHERE (SELECT count(*) FROM vault_membership m WHERE m.vault_id = vault.id AND m.status != 'revoked') > 1;
diff --git a/apps/api/drizzle/meta/0007_snapshot.json b/apps/api/drizzle/meta/0007_snapshot.json
new file mode 100644
index 00000000..7e0ce889
--- /dev/null
+++ b/apps/api/drizzle/meta/0007_snapshot.json
@@ -0,0 +1,1774 @@
+{
+ "version": "6",
+ "dialect": "sqlite",
+ "id": "3c5e57c5-f6bc-4863-a824-417df9e6e7f8",
+ "prevId": "91325ebc-6c89-495d-b45a-f2510b635d5f",
+ "tables": {
+ "account": {
+ "name": "account",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "issuer": {
+ "name": "issuer",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'local:credential'"
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "access_token": {
+ "name": "access_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "id_token": {
+ "name": "id_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "access_token_expires_at": {
+ "name": "access_token_expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "refresh_token_expires_at": {
+ "name": "refresh_token_expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(cast(unixepoch('subsecond') * 1000 as integer))"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "account_userId_idx": {
+ "name": "account_userId_idx",
+ "columns": [
+ "user_id"
+ ],
+ "isUnique": false
+ },
+ "account_issuer_accountId_uidx": {
+ "name": "account_issuer_accountId_uidx",
+ "columns": [
+ "issuer",
+ "account_id"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {
+ "account_user_id_user_id_fk": {
+ "name": "account_user_id_user_id_fk",
+ "tableFrom": "account",
+ "tableTo": "user",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "device_code": {
+ "name": "device_code",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "device_code": {
+ "name": "device_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_code": {
+ "name": "user_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "last_polled_at": {
+ "name": "last_polled_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "polling_interval": {
+ "name": "polling_interval",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "client_id": {
+ "name": "client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "device_code_deviceCode_uidx": {
+ "name": "device_code_deviceCode_uidx",
+ "columns": [
+ "device_code"
+ ],
+ "isUnique": true
+ },
+ "device_code_userCode_uidx": {
+ "name": "device_code_userCode_uidx",
+ "columns": [
+ "user_code"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "invitation": {
+ "name": "invitation",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'pending'"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(cast(unixepoch('subsecond') * 1000 as integer))"
+ },
+ "inviter_id": {
+ "name": "inviter_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "invitation_organizationId_idx": {
+ "name": "invitation_organizationId_idx",
+ "columns": [
+ "organization_id"
+ ],
+ "isUnique": false
+ },
+ "invitation_email_idx": {
+ "name": "invitation_email_idx",
+ "columns": [
+ "email"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "invitation_organization_id_organization_id_fk": {
+ "name": "invitation_organization_id_organization_id_fk",
+ "tableFrom": "invitation",
+ "tableTo": "organization",
+ "columnsFrom": [
+ "organization_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "invitation_inviter_id_user_id_fk": {
+ "name": "invitation_inviter_id_user_id_fk",
+ "tableFrom": "invitation",
+ "tableTo": "user",
+ "columnsFrom": [
+ "inviter_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "member": {
+ "name": "member",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'member'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "member_organizationId_idx": {
+ "name": "member_organizationId_idx",
+ "columns": [
+ "organization_id"
+ ],
+ "isUnique": false
+ },
+ "member_userId_idx": {
+ "name": "member_userId_idx",
+ "columns": [
+ "user_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "member_organization_id_organization_id_fk": {
+ "name": "member_organization_id_organization_id_fk",
+ "tableFrom": "member",
+ "tableTo": "organization",
+ "columnsFrom": [
+ "organization_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "member_user_id_user_id_fk": {
+ "name": "member_user_id_user_id_fk",
+ "tableFrom": "member",
+ "tableTo": "user",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "organization": {
+ "name": "organization",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "logo": {
+ "name": "logo",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "polar_customer_id": {
+ "name": "polar_customer_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "synced_vaults_override": {
+ "name": "synced_vaults_override",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "organization_slug_unique": {
+ "name": "organization_slug_unique",
+ "columns": [
+ "slug"
+ ],
+ "isUnique": true
+ },
+ "organization_polar_customer_id_unique": {
+ "name": "organization_polar_customer_id_unique",
+ "columns": [
+ "polar_customer_id"
+ ],
+ "isUnique": true
+ },
+ "organization_slug_uidx": {
+ "name": "organization_slug_uidx",
+ "columns": [
+ "slug"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "session": {
+ "name": "session",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(cast(unixepoch('subsecond') * 1000 as integer))"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "ip_address": {
+ "name": "ip_address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "user_agent": {
+ "name": "user_agent",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "active_organization_id": {
+ "name": "active_organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "session_token_unique": {
+ "name": "session_token_unique",
+ "columns": [
+ "token"
+ ],
+ "isUnique": true
+ },
+ "session_userId_idx": {
+ "name": "session_userId_idx",
+ "columns": [
+ "user_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "session_user_id_user_id_fk": {
+ "name": "session_user_id_user_id_fk",
+ "tableFrom": "session",
+ "tableTo": "user",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "user": {
+ "name": "user",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "email_verified": {
+ "name": "email_verified",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(cast(unixepoch('subsecond') * 1000 as integer))"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(cast(unixepoch('subsecond') * 1000 as integer))"
+ }
+ },
+ "indexes": {
+ "user_email_unique": {
+ "name": "user_email_unique",
+ "columns": [
+ "email"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "verification": {
+ "name": "verification",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(cast(unixepoch('subsecond') * 1000 as integer))"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(cast(unixepoch('subsecond') * 1000 as integer))"
+ }
+ },
+ "indexes": {
+ "verification_identifier_idx": {
+ "name": "verification_identifier_idx",
+ "columns": [
+ "identifier"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "polar_subscription": {
+ "name": "polar_subscription",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "product_id": {
+ "name": "product_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "polar_customer_id": {
+ "name": "polar_customer_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "polar_subscription_id": {
+ "name": "polar_subscription_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "polar_checkout_id": {
+ "name": "polar_checkout_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "period_start": {
+ "name": "period_start",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "period_end": {
+ "name": "period_end",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "cancel_at_period_end": {
+ "name": "cancel_at_period_end",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(cast(unixepoch('subsecond') * 1000 as integer))"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(cast(unixepoch('subsecond') * 1000 as integer))"
+ }
+ },
+ "indexes": {
+ "polar_subscription_organizationId_idx": {
+ "name": "polar_subscription_organizationId_idx",
+ "columns": [
+ "organization_id"
+ ],
+ "isUnique": false
+ },
+ "polar_subscription_customerId_idx": {
+ "name": "polar_subscription_customerId_idx",
+ "columns": [
+ "polar_customer_id"
+ ],
+ "isUnique": false
+ },
+ "polar_subscription_status_idx": {
+ "name": "polar_subscription_status_idx",
+ "columns": [
+ "status",
+ "period_end"
+ ],
+ "isUnique": false
+ },
+ "polar_subscription_polarSubscriptionId_uidx": {
+ "name": "polar_subscription_polarSubscriptionId_uidx",
+ "columns": [
+ "polar_subscription_id"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {
+ "polar_subscription_organization_id_organization_id_fk": {
+ "name": "polar_subscription_organization_id_organization_id_fk",
+ "tableFrom": "polar_subscription",
+ "tableTo": "organization",
+ "columnsFrom": [
+ "organization_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "vault": {
+ "name": "vault",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "shared_at": {
+ "name": "shared_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "active_key_version": {
+ "name": "active_key_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "purge_status": {
+ "name": "purge_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "purge_error": {
+ "name": "purge_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "vault_organizationId_idx": {
+ "name": "vault_organizationId_idx",
+ "columns": [
+ "organization_id"
+ ],
+ "isUnique": false
+ },
+ "vault_deletedAt_idx": {
+ "name": "vault_deletedAt_idx",
+ "columns": [
+ "deleted_at"
+ ],
+ "isUnique": false
+ },
+ "vault_organization_name_active_uidx": {
+ "name": "vault_organization_name_active_uidx",
+ "columns": [
+ "organization_id",
+ "name"
+ ],
+ "isUnique": true,
+ "where": "\"vault\".\"deleted_at\" is null"
+ }
+ },
+ "foreignKeys": {
+ "vault_organization_id_organization_id_fk": {
+ "name": "vault_organization_id_organization_id_fk",
+ "tableFrom": "vault",
+ "tableTo": "organization",
+ "columnsFrom": [
+ "organization_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "vault_key_wrapper": {
+ "name": "vault_key_wrapper",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "vault_id": {
+ "name": "vault_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "key_version": {
+ "name": "key_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "envelope_json": {
+ "name": "envelope_json",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "vault_key_wrapper_vaultId_idx": {
+ "name": "vault_key_wrapper_vaultId_idx",
+ "columns": [
+ "vault_id"
+ ],
+ "isUnique": false
+ },
+ "vault_key_wrapper_userId_idx": {
+ "name": "vault_key_wrapper_userId_idx",
+ "columns": [
+ "user_id"
+ ],
+ "isUnique": false
+ },
+ "vault_key_wrapper_vault_kind_user_unique": {
+ "name": "vault_key_wrapper_vault_kind_user_unique",
+ "columns": [
+ "vault_id",
+ "kind",
+ "user_id"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {
+ "vault_key_wrapper_vault_id_vault_id_fk": {
+ "name": "vault_key_wrapper_vault_id_vault_id_fk",
+ "tableFrom": "vault_key_wrapper",
+ "tableTo": "vault",
+ "columnsFrom": [
+ "vault_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "vault_key_wrapper_user_id_user_id_fk": {
+ "name": "vault_key_wrapper_user_id_user_id_fk",
+ "tableFrom": "vault_key_wrapper",
+ "tableTo": "user",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "vault_membership": {
+ "name": "vault_membership",
+ "columns": {
+ "vault_id": {
+ "name": "vault_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "access_version": {
+ "name": "access_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 1
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "joined_at": {
+ "name": "joined_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "explicit_access": {
+ "name": "explicit_access",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": true
+ },
+ "is_creator": {
+ "name": "is_creator",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ }
+ },
+ "indexes": {
+ "vault_membership_userId_status_idx": {
+ "name": "vault_membership_userId_status_idx",
+ "columns": [
+ "user_id",
+ "status"
+ ],
+ "isUnique": false
+ },
+ "vault_membership_vaultId_status_idx": {
+ "name": "vault_membership_vaultId_status_idx",
+ "columns": [
+ "vault_id",
+ "status"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "vault_membership_vault_id_vault_id_fk": {
+ "name": "vault_membership_vault_id_vault_id_fk",
+ "tableFrom": "vault_membership",
+ "tableTo": "vault",
+ "columnsFrom": [
+ "vault_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "vault_membership_user_id_user_id_fk": {
+ "name": "vault_membership_user_id_user_id_fk",
+ "tableFrom": "vault_membership",
+ "tableTo": "user",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "vault_membership_vault_id_user_id_pk": {
+ "columns": [
+ "vault_id",
+ "user_id"
+ ],
+ "name": "vault_membership_vault_id_user_id_pk"
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "vault_sync_status": {
+ "name": "vault_sync_status",
+ "columns": {
+ "vault_id": {
+ "name": "vault_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "health_status": {
+ "name": "health_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'unknown'"
+ },
+ "health_reasons_json": {
+ "name": "health_reasons_json",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'[]'"
+ },
+ "current_cursor": {
+ "name": "current_cursor",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "entry_count": {
+ "name": "entry_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "live_blob_count": {
+ "name": "live_blob_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "staged_blob_count": {
+ "name": "staged_blob_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "pending_delete_blob_count": {
+ "name": "pending_delete_blob_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "storage_used_bytes": {
+ "name": "storage_used_bytes",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "storage_limit_bytes": {
+ "name": "storage_limit_bytes",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "active_local_vault_count": {
+ "name": "active_local_vault_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "websocket_count": {
+ "name": "websocket_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "oldest_staged_blob_age_ms": {
+ "name": "oldest_staged_blob_age_ms",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "oldest_pending_delete_age_ms": {
+ "name": "oldest_pending_delete_age_ms",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "last_commit_at": {
+ "name": "last_commit_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "last_gc_at": {
+ "name": "last_gc_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "last_flushed_at": {
+ "name": "last_flushed_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "vault_sync_status_health_idx": {
+ "name": "vault_sync_status_health_idx",
+ "columns": [
+ "health_status",
+ "updated_at"
+ ],
+ "isUnique": false
+ },
+ "vault_sync_status_storage_idx": {
+ "name": "vault_sync_status_storage_idx",
+ "columns": [
+ "storage_used_bytes",
+ "storage_limit_bytes"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "vault_sync_status_vault_id_vault_id_fk": {
+ "name": "vault_sync_status_vault_id_vault_id_fk",
+ "tableFrom": "vault_sync_status",
+ "tableTo": "vault",
+ "columnsFrom": [
+ "vault_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "invitation_vault": {
+ "name": "invitation_vault",
+ "columns": {
+ "invitation_id": {
+ "name": "invitation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "vault_id": {
+ "name": "vault_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "invitation_vault_invitation_id_invitation_id_fk": {
+ "name": "invitation_vault_invitation_id_invitation_id_fk",
+ "tableFrom": "invitation_vault",
+ "tableTo": "invitation",
+ "columnsFrom": [
+ "invitation_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "invitation_vault_vault_id_vault_id_fk": {
+ "name": "invitation_vault_vault_id_vault_id_fk",
+ "tableFrom": "invitation_vault",
+ "tableTo": "vault",
+ "columnsFrom": [
+ "vault_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "invitation_vault_invitation_id_vault_id_pk": {
+ "columns": [
+ "invitation_id",
+ "vault_id"
+ ],
+ "name": "invitation_vault_invitation_id_vault_id_pk"
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "sharing_audit": {
+ "name": "sharing_audit",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "action": {
+ "name": "action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "target_id": {
+ "name": "target_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "sharing_audit_org_idx": {
+ "name": "sharing_audit_org_idx",
+ "columns": [
+ "organization_id",
+ "created_at"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "sharing_audit_organization_id_organization_id_fk": {
+ "name": "sharing_audit_organization_id_organization_id_fk",
+ "tableFrom": "sharing_audit",
+ "tableTo": "organization",
+ "columnsFrom": [
+ "organization_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "sharing_refresh": {
+ "name": "sharing_refresh",
+ "columns": {
+ "vault_id": {
+ "name": "vault_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "revision": {
+ "name": "revision",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "sharing_refresh_vault_id_vault_id_fk": {
+ "name": "sharing_refresh_vault_id_vault_id_fk",
+ "tableFrom": "sharing_refresh",
+ "tableTo": "vault",
+ "columnsFrom": [
+ "vault_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "vault_key_request": {
+ "name": "vault_key_request",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "vault_id": {
+ "name": "vault_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "purpose": {
+ "name": "purpose",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "access_version": {
+ "name": "access_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "public_key": {
+ "name": "public_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "envelope_json": {
+ "name": "envelope_json",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "approved_by": {
+ "name": "approved_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "vault_key_request_vault_status_idx": {
+ "name": "vault_key_request_vault_status_idx",
+ "columns": [
+ "vault_id",
+ "status"
+ ],
+ "isUnique": false
+ },
+ "vault_key_request_user_idx": {
+ "name": "vault_key_request_user_idx",
+ "columns": [
+ "user_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "vault_key_request_vault_id_vault_id_fk": {
+ "name": "vault_key_request_vault_id_vault_id_fk",
+ "tableFrom": "vault_key_request",
+ "tableTo": "vault",
+ "columnsFrom": [
+ "vault_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "vault_key_request_user_id_user_id_fk": {
+ "name": "vault_key_request_user_id_user_id_fk",
+ "tableFrom": "vault_key_request",
+ "tableTo": "user",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "vault_key_request_approved_by_user_id_fk": {
+ "name": "vault_key_request_approved_by_user_id_fk",
+ "tableFrom": "vault_key_request",
+ "tableTo": "user",
+ "columnsFrom": [
+ "approved_by"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ }
+ },
+ "views": {},
+ "enums": {},
+ "_meta": {
+ "schemas": {},
+ "tables": {},
+ "columns": {}
+ },
+ "internal": {
+ "indexes": {}
+ }
+}
diff --git a/apps/api/drizzle/meta/_journal.json b/apps/api/drizzle/meta/_journal.json
index 9e91c535..1542a486 100644
--- a/apps/api/drizzle/meta/_journal.json
+++ b/apps/api/drizzle/meta/_journal.json
@@ -50,6 +50,13 @@
"when": 1787664774337,
"tag": "0006_mute_bloodstrike",
"breakpoints": true
+ },
+ {
+ "idx": 7,
+ "version": "6",
+ "when": 1790485061751,
+ "tag": "0007_plus_sharing",
+ "breakpoints": true
}
]
}
\ No newline at end of file
diff --git a/apps/api/public/i18n/de.json b/apps/api/public/i18n/de.json
index 8a068e77..aff04571 100644
--- a/apps/api/public/i18n/de.json
+++ b/apps/api/public/i18n/de.json
@@ -87,7 +87,7 @@
"createNameLabel": "Vault-Name",
"createPasswordLabel": "Vault-Passwort",
"createConfirmPasswordLabel": "Vault-Passwort (Bestätigung)",
- "createPasswordHint": "Das Passwort kann nicht wiederhergestellt werden. Bewahren Sie es sicher auf. Geben Sie dasselbe Passwort ein, wenn Sie dieses Vault in Obsidian verbinden.",
+ "createPasswordHint": "Bewahre dieses Passwort sicher auf. Bei Verlust muss ein anderer Vault-Administrator, der den Vault-Schlüssel noch besitzt, die Wiederherstellung genehmigen.",
"createConfirm": "Vault erstellen",
"creating": "Wird erstellt...",
"createdVault": "{name} wurde erstellt. Verbinden Sie es in Obsidian mit demselben Vault-Passwort.",
@@ -132,6 +132,85 @@
"queuedForDeletion": "{name} wurde in die Löschwarteschlange gestellt.",
"unknown": "Unbekannt",
"created": "Erstellt am {date}",
- "deletionStatus": "Löschen {status}"
+ "deletionStatus": "Löschen {status}",
+ "organization": "Organisation",
+ "organizations": "Organisationen verwalten"
+ },
+ "organizations": {
+ "title": "Organisationen",
+ "subtitle": "Verwalte Mitglieder, Einladungen und den Zugriff auf verschlüsselte Vaults.",
+ "name": "Organisationsname",
+ "rename": "Umbenennen",
+ "organizationRole": "Organisationsrolle",
+ "role": "Rolle",
+ "email": "E-Mail-Adresse",
+ "invite": "Mitglied einladen",
+ "inviteHelp": "Wähle die Vaults, auf die dieses Mitglied zugreifen und die es bearbeiten kann. Eigentümer und Administratoren können auf alle Vaults zugreifen und sie verwalten. Ausstehende Einladungen reservieren Mitgliedsplätze.",
+ "selectVault": "Wähle mindestens einen Vault.",
+ "sent": "Einladungs-E-Mail gesendet.",
+ "copyLink": "Kopiere diesen Link und teile ihn mit der eingeladenen Person. Sie muss sich mit der eingeladenen E-Mail-Adresse anmelden.",
+ "inviteLink": "Einladungslink",
+ "invitations": "Einladungen",
+ "members": "Mitglieder",
+ "remove": "Mitglied entfernen",
+ "revoke": "Zugriff entziehen",
+ "grant": "Zugriff gewähren",
+ "leave": "Organisation verlassen",
+ "removeConfirm": "Synchronisierung für diese Person beenden? Bereits heruntergeladene Dateien bleiben auf ihren Geräten.",
+ "pendingRefresh": "Zugriff entzogen. Bestehende Verbindungen werden geschlossen. Aktualisiere die Seite zur Kontrolle.",
+ "noAccess": "Kein Zugriff",
+ "yourAccess": "Dein Zugriff",
+ "owner": "Eigentümer",
+ "admin": "Administrator",
+ "member": "Mitglied",
+ "active": "Aktiv",
+ "pending_key": "Wartet auf Schlüsseleinrichtung",
+ "revoked": "Entzogen",
+ "pending": "Ausstehend",
+ "expired": "Abgelaufen",
+ "canceled": "Abgebrochen",
+ "rejected": "Abgelehnt",
+ "accepted": "Angenommen",
+ "refresh": "Aktualisieren",
+ "working": "Speichern…",
+ "saved": "Gespeichert.",
+ "failed": "Anfrage konnte nicht abgeschlossen werden.",
+ "signIn": "Bitte melde dich an.",
+ "loaded": "Organisation geladen.",
+ "noOrganizations": "Keine Organisationen gefunden.",
+ "noVaults": "Keine Vaults verfügbar. Erstelle einen unter Remote-Vaults oder bitte einen Administrator um Zugriff.",
+ "suspended": "Gemeinsame Synchronisierung pausiert. Die Daten bleiben erhalten. Nach Erneuerung von Plus wird der Zugriff fortgesetzt.",
+ "keyHelp": "Öffne in Obsidian Synch → Vault-Freigabe und Passwörter, um Zugriff anzufordern oder zu genehmigen und dein eigenes Passwort festzulegen. Gespeicherte Versionen werden ebenfalls geteilt.",
+ "plusLimits": "Plus: 3 Mitglieder einschließlich Eigentümer · 3 Vaults · 2 GB pro Vault · 100 MB pro Datei · 1 Jahr Versionsverlauf",
+ "cancel": "Einladung abbrechen",
+ "resend": "Erneut senden",
+ "vaults": "Remote-Vaults",
+ "organization": "Organisation",
+ "billing": "Abrechnung verwalten",
+ "sharingRequired": "Organisationsfreigaben sind mit Plus oder auf selbst gehosteten Servern verfügbar."
+ },
+ "invitations": {
+ "organizationRole": "Organisationsrolle",
+ "owner": "Eigentümer",
+ "admin": "Administrator",
+ "member": "Mitglied",
+ "pending": "Ausstehend",
+ "expired": "Abgelaufen",
+ "canceled": "Abgebrochen",
+ "rejected": "Abgelehnt",
+ "accepted": "Angenommen",
+ "failed": "Anfrage konnte nicht abgeschlossen werden.",
+ "signIn": "Bitte melde dich an.",
+ "title": "Organisationseinladung",
+ "subtitle": "Prüfe die Vault-Berechtigungen dieser Einladung.",
+ "missing": "Öffne den Einladungslink deines Administrators.",
+ "history": "Nach Annahme und Schlüsselfreigabe erhältst du auch Zugriff auf gespeicherte Versionen.",
+ "keyHelp": "Öffne nach der Annahme im Synch-Obsidian-Plugin auf deinem Gerät die Vault-Freigabe und Passwörter. Fordere eine Administratorfreigabe an und lege dein eigenes Passwort fest.",
+ "accept": "Einladung annehmen",
+ "reject": "Einladung ablehnen",
+ "next": "Einladung angenommen. Setze die Schlüsseleinrichtung in Obsidian fort.",
+ "organizations": "Organisation verwalten",
+ "switchAccount": "Konto wechseln",
+ "wrongAccount": "Diese Einladung ist für dieses Konto nicht verfügbar. Melde dich mit der eingeladenen E-Mail-Adresse an."
}
}
diff --git a/apps/api/public/i18n/ja.json b/apps/api/public/i18n/ja.json
index 024da174..63509c86 100644
--- a/apps/api/public/i18n/ja.json
+++ b/apps/api/public/i18n/ja.json
@@ -87,7 +87,7 @@
"createNameLabel": "Vault 名",
"createPasswordLabel": "Vault パスワード",
"createConfirmPasswordLabel": "Vault パスワード(確認)",
- "createPasswordHint": "パスワードは復元できないため、安全な場所に保管してください。Obsidian からこの vault に接続する際に同じパスワードを入力します。",
+ "createPasswordHint": "パスワードを安全に保管してください。紛失時の復旧にはvaultキーを持つ別のvault管理者の承認が必要です。",
"createConfirm": "Vault を作成",
"creating": "作成中...",
"createdVault": "{name} を作成しました。Obsidian から同じ vault パスワードで接続してください。",
@@ -132,6 +132,85 @@
"queuedForDeletion": "{name}を削除キューに追加しました。",
"unknown": "不明",
"created": "作成日 {date}",
- "deletionStatus": "削除 {status}"
+ "deletionStatus": "削除 {status}",
+ "organization": "組織",
+ "organizations": "組織を管理"
+ },
+ "organizations": {
+ "title": "組織の管理",
+ "subtitle": "メンバー、招待、暗号化された Vault へのアクセスを管理します。",
+ "name": "組織名",
+ "rename": "名前を変更",
+ "organizationRole": "組織の役割",
+ "role": "役割",
+ "email": "メールアドレス",
+ "invite": "メンバーを招待",
+ "inviteHelp": "メンバーがアクセス・編集できる保管庫を選択してください。所有者と管理者はすべての保管庫にアクセスして管理できます。保留中の招待もメンバー数に含まれます。",
+ "selectVault": "Vault を1つ以上選択してください。",
+ "sent": "招待メールを送信しました。",
+ "copyLink": "この招待リンクをコピーして相手に伝えてください。招待されたメールアドレスでログインする必要があります。",
+ "inviteLink": "招待リンク",
+ "invitations": "招待",
+ "members": "メンバー",
+ "remove": "メンバーを削除",
+ "revoke": "アクセスを取り消す",
+ "grant": "アクセスを許可",
+ "leave": "組織から退出",
+ "removeConfirm": "この人の同期アクセスを停止しますか?端末にダウンロード済みのファイルは残ります。",
+ "pendingRefresh": "アクセスを取り消しました。既存の接続を終了中です。更新して確認してください。",
+ "noAccess": "アクセスなし",
+ "yourAccess": "自分の権限",
+ "owner": "所有者",
+ "admin": "管理者",
+ "member": "メンバー",
+ "active": "有効",
+ "pending_key": "キー設定待ち",
+ "revoked": "取り消し済み",
+ "pending": "承諾待ち",
+ "expired": "期限切れ",
+ "canceled": "キャンセル済み",
+ "rejected": "拒否済み",
+ "accepted": "承諾済み",
+ "refresh": "更新",
+ "working": "保存中…",
+ "saved": "保存しました。",
+ "failed": "リクエストを完了できません。",
+ "signIn": "ログインしてください。",
+ "loaded": "組織を読み込みました。",
+ "noOrganizations": "組織がありません。",
+ "noVaults": "利用可能な Vault がありません。リモート Vault で作成するか、管理者にアクセスを申請してください。",
+ "suspended": "共有同期は停止中です。データは保持され、Plus を再契約するとアクセスが再開します。",
+ "keyHelp": "Obsidian の Synch → Vault の共有とパスワードでアクセスを申請・承認し、自分の Vault パスワードを設定してください。保存済みの履歴も共有されます。",
+ "plusLimits": "Plus:所有者を含む3名 · Vault 3個 · 各 Vault 2 GB · ファイルあたり100 MB · 履歴1年",
+ "cancel": "招待をキャンセル",
+ "resend": "再送信",
+ "vaults": "リモート Vault",
+ "organization": "組織",
+ "billing": "請求を管理",
+ "sharingRequired": "Plusまたはセルフホスト環境で組織のvaultを共有できます。"
+ },
+ "invitations": {
+ "organizationRole": "組織の役割",
+ "owner": "所有者",
+ "admin": "管理者",
+ "member": "メンバー",
+ "pending": "承諾待ち",
+ "expired": "期限切れ",
+ "canceled": "キャンセル済み",
+ "rejected": "拒否済み",
+ "accepted": "承諾済み",
+ "failed": "リクエストを完了できません。",
+ "signIn": "ログインしてください。",
+ "title": "組織への招待",
+ "subtitle": "招待に含まれる Vault のアクセス権を確認してください。",
+ "missing": "管理者から受け取った招待リンクを開いてください。",
+ "history": "承諾してキーの承認を受けると、保存済みの履歴にもアクセスできます。",
+ "keyHelp": "承諾後、使用する端末の Synch Obsidian プラグインで Vault の共有とパスワードを開き、管理者に承認を申請して自分のパスワードを設定してください。",
+ "accept": "招待を承諾",
+ "reject": "招待を拒否",
+ "next": "招待を承諾しました。Obsidian でキー設定を続けてください。",
+ "organizations": "組織を管理",
+ "switchAccount": "アカウントを切り替え",
+ "wrongAccount": "このアカウントでは招待を開けません。招待を受け取ったメールアドレスでログインしてください。"
}
}
diff --git a/apps/api/public/i18n/ko.json b/apps/api/public/i18n/ko.json
index 7e034508..f484a58c 100644
--- a/apps/api/public/i18n/ko.json
+++ b/apps/api/public/i18n/ko.json
@@ -87,7 +87,7 @@
"createNameLabel": "Vault 이름",
"createPasswordLabel": "Vault 비밀번호",
"createConfirmPasswordLabel": "Vault 비밀번호 확인",
- "createPasswordHint": "비밀번호는 복구할 수 없으니 안전한 곳에 보관하세요. Obsidian에서 이 vault를 연결할 때 같은 비밀번호를 입력합니다.",
+ "createPasswordHint": "비밀번호를 안전하게 보관하세요. 분실 시 vault 키를 가진 다른 vault 관리자의 승인이 있어야 복구할 수 있습니다.",
"createConfirm": "Vault 생성",
"creating": "생성 중...",
"createdVault": "{name}이(가) 생성되었습니다. Obsidian에서 같은 vault 비밀번호로 연결하세요.",
@@ -132,6 +132,85 @@
"queuedForDeletion": "{name} 삭제가 대기열에 추가되었습니다.",
"unknown": "알 수 없음",
"created": "생성일 {date}",
- "deletionStatus": "삭제 {status}"
+ "deletionStatus": "삭제 {status}",
+ "organization": "조직",
+ "organizations": "조직 관리"
+ },
+ "organizations": {
+ "title": "조직 관리",
+ "subtitle": "멤버, 초대, 암호화된 vault의 접근 권한을 관리합니다.",
+ "name": "조직 이름",
+ "rename": "이름 변경",
+ "organizationRole": "조직 역할",
+ "role": "역할",
+ "email": "이메일 주소",
+ "invite": "멤버 초대",
+ "inviteHelp": "멤버가 접근하고 편집할 vault를 선택하세요. 소유자와 관리자는 모든 vault에 접근하고 관리할 수 있습니다. 대기 중인 초대도 멤버 수에 포함됩니다.",
+ "selectVault": "Vault를 하나 이상 선택하세요.",
+ "sent": "초대 이메일을 보냈습니다.",
+ "copyLink": "초대 링크를 복사해 초대한 사람에게 전달하세요. 초대받은 이메일 주소로 로그인해야 합니다.",
+ "inviteLink": "초대 링크",
+ "invitations": "초대",
+ "members": "멤버",
+ "remove": "멤버 제거",
+ "revoke": "접근 회수",
+ "grant": "접근 허용",
+ "leave": "조직 탈퇴",
+ "removeConfirm": "이 사람의 동기화 접근을 중지할까요? 이미 기기에 내려받은 파일은 유지됩니다.",
+ "pendingRefresh": "접근 권한을 회수했습니다. 기존 연결을 종료 중이니 새로고침해 확인하세요.",
+ "noAccess": "접근 없음",
+ "yourAccess": "내 권한",
+ "owner": "소유자",
+ "admin": "관리자",
+ "member": "멤버",
+ "active": "활성",
+ "pending_key": "키 설정 대기",
+ "revoked": "회수됨",
+ "pending": "수락 대기",
+ "expired": "만료됨",
+ "canceled": "취소됨",
+ "rejected": "거절됨",
+ "accepted": "수락됨",
+ "refresh": "새로고침",
+ "working": "저장 중…",
+ "saved": "저장했습니다.",
+ "failed": "요청을 완료할 수 없습니다.",
+ "signIn": "로그인해 주세요.",
+ "loaded": "조직을 불러왔습니다.",
+ "noOrganizations": "조직이 없습니다.",
+ "noVaults": "사용 가능한 vault가 없습니다. 원격 vault에서 생성하거나 관리자에게 접근을 요청하세요.",
+ "suspended": "공유 동기화가 중지되었습니다. 데이터는 보존되며 Plus를 재구독하면 접근이 재개됩니다.",
+ "keyHelp": "Obsidian의 Synch → Vault 공유 및 비밀번호에서 접근을 요청·승인하고 개인 vault 비밀번호를 설정하세요. 보관된 과거 이력도 공유됩니다.",
+ "plusLimits": "Plus: 소유자 포함 3명 · Vault 3개 · Vault별 2 GB · 파일당 100 MB · 이력 1년",
+ "cancel": "초대 취소",
+ "resend": "재전송",
+ "vaults": "원격 vault",
+ "organization": "조직",
+ "billing": "구독 관리",
+ "sharingRequired": "Plus 또는 self-hosted에서 조직의 vault를 공유할 수 있습니다."
+ },
+ "invitations": {
+ "organizationRole": "조직 역할",
+ "owner": "소유자",
+ "admin": "관리자",
+ "member": "멤버",
+ "pending": "수락 대기",
+ "expired": "만료됨",
+ "canceled": "취소됨",
+ "rejected": "거절됨",
+ "accepted": "수락됨",
+ "failed": "요청을 완료할 수 없습니다.",
+ "signIn": "로그인해 주세요.",
+ "title": "조직 초대",
+ "subtitle": "초대에 포함된 vault 접근 권한을 확인하세요.",
+ "missing": "관리자가 제공한 초대 링크를 열어주세요.",
+ "history": "초대를 수락하고 키 승인을 받으면 보관된 과거 이력에도 접근할 수 있습니다.",
+ "keyHelp": "수락 후 사용할 기기의 Synch Obsidian 플러그인에서 Vault 공유 및 비밀번호를 열어 관리자 승인을 요청하고 자신의 vault 비밀번호를 설정하세요.",
+ "accept": "초대 수락",
+ "reject": "초대 거절",
+ "next": "초대를 수락했습니다. Obsidian에서 키 설정을 계속하세요.",
+ "organizations": "조직 관리",
+ "switchAccount": "계정 전환",
+ "wrongAccount": "이 계정에서는 초대를 열 수 없습니다. 초대를 받은 이메일 주소로 로그인하세요."
}
}
diff --git a/apps/api/public/i18n/zh-cn.json b/apps/api/public/i18n/zh-cn.json
index 69e3b0aa..0121a064 100644
--- a/apps/api/public/i18n/zh-cn.json
+++ b/apps/api/public/i18n/zh-cn.json
@@ -87,7 +87,7 @@
"createNameLabel": "Vault 名称",
"createPasswordLabel": "Vault 密码",
"createConfirmPasswordLabel": "确认 vault 密码",
- "createPasswordHint": "密码无法找回,请妥善保管。在 Obsidian 中连接此 vault 时需要输入相同的密码。",
+ "createPasswordHint": "请妥善保管密码。丢失后,需要仍持有 vault 密钥的其他 vault 管理员批准才能恢复。",
"createConfirm": "创建 vault",
"creating": "创建中...",
"createdVault": "{name} 已创建。请在 Obsidian 中使用相同的 vault 密码连接。",
@@ -132,6 +132,85 @@
"queuedForDeletion": "{name} 已加入删除队列。",
"unknown": "未知",
"created": "创建于 {date}",
- "deletionStatus": "删除 {status}"
+ "deletionStatus": "删除 {status}",
+ "organization": "组织",
+ "organizations": "管理组织"
+ },
+ "organizations": {
+ "title": "组织管理",
+ "subtitle": "管理成员、邀请以及加密 Vault 的访问权限。",
+ "name": "组织名称",
+ "rename": "重命名",
+ "organizationRole": "组织角色",
+ "role": "角色",
+ "email": "电子邮件地址",
+ "invite": "邀请成员",
+ "inviteHelp": "选择此成员可以访问和编辑的保险库。所有者和管理员可以访问和管理所有保险库。待处理的邀请也会占用成员名额。",
+ "selectVault": "请至少选择一个 Vault。",
+ "sent": "邀请邮件已发送。",
+ "copyLink": "复制此邀请链接并发送给受邀人。对方必须使用受邀的电子邮件地址登录。",
+ "inviteLink": "邀请链接",
+ "invitations": "邀请",
+ "members": "成员",
+ "remove": "移除成员",
+ "revoke": "撤销访问",
+ "grant": "授予访问",
+ "leave": "退出组织",
+ "removeConfirm": "停止此人的同步访问?已下载到设备上的文件仍会保留。",
+ "pendingRefresh": "访问权限已撤销,正在关闭现有连接。请刷新以确认。",
+ "noAccess": "无访问权限",
+ "yourAccess": "我的权限",
+ "owner": "所有者",
+ "admin": "管理员",
+ "member": "成员",
+ "active": "已启用",
+ "pending_key": "等待密钥设置",
+ "revoked": "已撤销",
+ "pending": "待接受",
+ "expired": "已过期",
+ "canceled": "已取消",
+ "rejected": "已拒绝",
+ "accepted": "已接受",
+ "refresh": "刷新",
+ "working": "保存中…",
+ "saved": "已保存。",
+ "failed": "无法完成请求。",
+ "signIn": "请登录。",
+ "loaded": "组织已加载。",
+ "noOrganizations": "没有组织。",
+ "noVaults": "没有可用的 Vault。请在远程 Vault 中创建,或向管理员申请访问。",
+ "suspended": "共享同步已暂停。数据会保留,续订 Plus 后将恢复访问。",
+ "keyHelp": "在 Obsidian 的 Synch → Vault 共享与密码中申请或批准访问,并设置个人 Vault 密码。保留的历史记录也会共享。",
+ "plusLimits": "Plus:含所有者共 3 人 · 3 个 Vault · 每个 Vault 2 GB · 每个文件 100 MB · 1 年历史记录",
+ "cancel": "取消邀请",
+ "resend": "重新发送",
+ "vaults": "远程 Vault",
+ "organization": "组织",
+ "billing": "管理订阅",
+ "sharingRequired": "Plus 或自托管服务器支持组织 vault 共享。"
+ },
+ "invitations": {
+ "organizationRole": "组织角色",
+ "owner": "所有者",
+ "admin": "管理员",
+ "member": "成员",
+ "pending": "待接受",
+ "expired": "已过期",
+ "canceled": "已取消",
+ "rejected": "已拒绝",
+ "accepted": "已接受",
+ "failed": "无法完成请求。",
+ "signIn": "请登录。",
+ "title": "组织邀请",
+ "subtitle": "查看此邀请包含的 Vault 访问权限。",
+ "missing": "请打开管理员提供的邀请链接。",
+ "history": "接受邀请并获得密钥批准后,你也可以访问保留的历史记录。",
+ "keyHelp": "接受后,在所用设备的 Synch Obsidian 插件中打开 Vault 共享与密码,申请管理员批准并设置自己的 Vault 密码。",
+ "accept": "接受邀请",
+ "reject": "拒绝邀请",
+ "next": "邀请已接受。请在 Obsidian 中继续设置密钥。",
+ "organizations": "管理组织",
+ "switchAccount": "切换账号",
+ "wrongAccount": "此账号无法查看邀请。请使用收到邀请的邮箱登录。"
}
}
diff --git a/apps/api/public/i18n/zh-tw.json b/apps/api/public/i18n/zh-tw.json
index 77041369..915b622f 100644
--- a/apps/api/public/i18n/zh-tw.json
+++ b/apps/api/public/i18n/zh-tw.json
@@ -87,7 +87,7 @@
"createNameLabel": "Vault 名稱",
"createPasswordLabel": "Vault 密碼",
"createConfirmPasswordLabel": "確認 vault 密碼",
- "createPasswordHint": "密碼無法復原,請妥善保管。在 Obsidian 連接此 vault 時需要輸入相同的密碼。",
+ "createPasswordHint": "請妥善保管密碼。遺失後,須由仍持有 vault 金鑰的其他 vault 管理員批准才能復原。",
"createConfirm": "建立 vault",
"creating": "建立中...",
"createdVault": "{name} 已建立。請在 Obsidian 使用相同的 vault 密碼連接。",
@@ -132,6 +132,85 @@
"queuedForDeletion": "{name} 已加入刪除佇列。",
"unknown": "未知",
"created": "建立於 {date}",
- "deletionStatus": "刪除 {status}"
+ "deletionStatus": "刪除 {status}",
+ "organization": "組織",
+ "organizations": "管理組織"
+ },
+ "organizations": {
+ "title": "組織管理",
+ "subtitle": "管理成員、邀請以及加密 Vault 的存取權限。",
+ "name": "組織名稱",
+ "rename": "重新命名",
+ "organizationRole": "組織角色",
+ "role": "角色",
+ "email": "電子郵件地址",
+ "invite": "邀請成員",
+ "inviteHelp": "選擇此成員可以存取和編輯的保管庫。擁有者和管理員可以存取和管理所有保管庫。待處理的邀請也會占用成員名額。",
+ "selectVault": "請至少選擇一個 Vault。",
+ "sent": "邀請郵件已傳送。",
+ "copyLink": "複製此邀請連結並傳送給受邀人。對方必須使用受邀的電子郵件地址登入。",
+ "inviteLink": "邀請連結",
+ "invitations": "邀請",
+ "members": "成員",
+ "remove": "移除成員",
+ "revoke": "撤銷存取",
+ "grant": "授予存取",
+ "leave": "退出組織",
+ "removeConfirm": "停止此人的同步存取?已下載到裝置上的檔案仍會保留。",
+ "pendingRefresh": "存取權限已撤銷,正在關閉現有連線。請重新整理以確認。",
+ "noAccess": "無存取權限",
+ "yourAccess": "我的權限",
+ "owner": "擁有者",
+ "admin": "管理員",
+ "member": "成員",
+ "active": "已啟用",
+ "pending_key": "等待金鑰設定",
+ "revoked": "已撤銷",
+ "pending": "待接受",
+ "expired": "已過期",
+ "canceled": "已取消",
+ "rejected": "已拒絕",
+ "accepted": "已接受",
+ "refresh": "重新整理",
+ "working": "儲存中…",
+ "saved": "已儲存。",
+ "failed": "無法完成請求。",
+ "signIn": "請登入。",
+ "loaded": "組織已載入。",
+ "noOrganizations": "沒有組織。",
+ "noVaults": "沒有可用的 Vault。請在遠端 Vault 中建立,或向管理員申請存取。",
+ "suspended": "共享同步已暫停。資料會保留,續訂 Plus 後將恢復存取。",
+ "keyHelp": "在 Obsidian 的 Synch → Vault 共享與密碼中申請或核准存取,並設定個人 Vault 密碼。保留的歷史紀錄也會共享。",
+ "plusLimits": "Plus:含擁有者共 3 人 · 3 個 Vault · 每個 Vault 2 GB · 每個檔案 100 MB · 1 年歷史紀錄",
+ "cancel": "取消邀請",
+ "resend": "重新傳送",
+ "vaults": "遠端 Vault",
+ "organization": "組織",
+ "billing": "管理訂閱",
+ "sharingRequired": "Plus 或自架伺服器支援組織 vault 共享。"
+ },
+ "invitations": {
+ "organizationRole": "組織角色",
+ "owner": "擁有者",
+ "admin": "管理員",
+ "member": "成員",
+ "pending": "待接受",
+ "expired": "已過期",
+ "canceled": "已取消",
+ "rejected": "已拒絕",
+ "accepted": "已接受",
+ "failed": "無法完成請求。",
+ "signIn": "請登入。",
+ "title": "組織邀請",
+ "subtitle": "查看此邀請包含的 Vault 存取權限。",
+ "missing": "請開啟管理員提供的邀請連結。",
+ "history": "接受邀請並取得金鑰核准後,你也可以存取保留的歷史紀錄。",
+ "keyHelp": "接受後,在使用裝置的 Synch Obsidian 外掛中開啟 Vault 共享與密碼,申請管理員核准並設定自己的 Vault 密碼。",
+ "accept": "接受邀請",
+ "reject": "拒絕邀請",
+ "next": "邀請已接受。請在 Obsidian 中繼續設定金鑰。",
+ "organizations": "管理組織",
+ "switchAccount": "切換帳號",
+ "wrongAccount": "此帳號無法查看邀請。請使用收到邀請的信箱登入。"
}
}
diff --git a/apps/api/public/invitations.html b/apps/api/public/invitations.html
new file mode 100644
index 00000000..9a5f16e9
--- /dev/null
+++ b/apps/api/public/invitations.html
@@ -0,0 +1,93 @@
+
+
+
+
+
+ Synch invitation
+
+
+
+
+
+
+
+
+
+ …
+
+
+
+
+
diff --git a/apps/api/public/organization-ui.js b/apps/api/public/organization-ui.js
new file mode 100644
index 00000000..f684b866
--- /dev/null
+++ b/apps/api/public/organization-ui.js
@@ -0,0 +1,6 @@
+// Organization management depends on role; sharing actions check plan entitlement.
+window.synchOrganizationUI = {
+ canManage(organization) {
+ return ["owner", "admin"].includes(organization?.role);
+ },
+};
diff --git a/apps/api/public/organizations.html b/apps/api/public/organizations.html
new file mode 100644
index 00000000..bb79e32a
--- /dev/null
+++ b/apps/api/public/organizations.html
@@ -0,0 +1,211 @@
+
+
+
+
+
+ Synch organizations
+
+
+
+
+
+
+
+
+
+
+ …
+
+
+
+
+
diff --git a/apps/api/public/styles.css b/apps/api/public/styles.css
index ae8837cc..dc6d42a1 100644
--- a/apps/api/public/styles.css
+++ b/apps/api/public/styles.css
@@ -742,3 +742,86 @@ dialog::backdrop {
width: 480px;
}
}
+
+/* Organization management keeps actions beside their scope on wide screens. */
+.org-toolbar, .org-inline, .org-row { display: flex; align-items: end; gap: 0.75rem; flex-wrap: wrap; }
+.org-toolbar { margin: 1.5rem 0; align-items: center; }
+.org-toolbar .input { width: auto; min-width: 12rem; flex: 1; }
+.org-detail { display: grid; gap: 1.25rem; margin-top: 1.25rem; }
+.org-panel { border: 1px solid var(--zinc-800); border-radius: 0.75rem; padding: 1.5rem; display: grid; gap: 1rem; }
+.org-heading { font-size: 1.125rem; font-weight: 600; color: var(--zinc-100); line-height: 1.5; }
+.org-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
+.org-form p { grid-column: 1 / -1; }
+.org-field { display: grid; gap: 0.5rem; flex: 1; min-width: 10rem; }
+.org-person { flex: 1; min-width: 12rem; overflow-wrap: anywhere; }
+.org-row { align-items: center; padding: 0.75rem 0; border-bottom: 1px solid var(--zinc-800); }
+.org-row .input, .org-inline > .input { width: auto; }
+.org-warning { color: #fbbf24; }
+.org-panel ul { padding-left: 1.25rem; }
+@media (max-width: 600px) { .org-form { grid-template-columns: 1fr; } .org-panel { padding: 1rem; } .org-row .input { flex: 1; } }
+
+.organization-topbar { justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
+
+/* Organization settings follow the document order at every viewport width. */
+.organizations-page { background: #0d0e10; font-size: 1rem; line-height: 1.6; }
+.organization-page { max-width: 50rem; padding-block: 1.5rem 4rem; }
+.organization-page .organization-topbar { margin-bottom: 1.75rem; padding-bottom: 1rem; border-bottom: 1px solid var(--zinc-800); }
+.organization-page .brand { font-size: 0.875rem; line-height: 1.5; font-weight: 650; letter-spacing: 0.14em; }
+.organization-page .vaults-header { margin-bottom: 1.5rem; }
+.organization-page .page-title { font-size: 1.875rem; font-weight: 600; line-height: 1.3; }
+.organization-page .vaults-subtitle { font-size: 1rem; color: var(--zinc-400); }
+.organization-page .org-toolbar { margin: 0; padding: 0.75rem 0; }
+.organization-page .org-toolbar .input { flex: 0 1 16rem; min-width: 0; }
+.organization-page #vaults-link { margin-left: auto; font-size: 1rem; color: var(--zinc-300); }
+.organization-page #vaults-link::after, .organization-page .org-billing::after { content: ' ↗'; color: var(--zinc-500); }
+.organization-page #status { font-size: 0.9375rem; }
+.organization-page #status:empty { display: none; }
+.organization-page #status[data-kind="error"] { color: var(--red-400); }
+.organization-page .org-detail { grid-template-columns: minmax(0, 1fr); gap: 0; margin-top: 0.75rem; }
+.organization-page .org-panel { background: transparent; border: 0; border-top: 1px solid #2a2b30; border-radius: 0; padding: 1.5rem 0; gap: 1rem; align-content: start; min-width: 0; }
+.organization-page .org-heading { font-size: 1.25rem; font-weight: 600; letter-spacing: -0.02em; }
+.organization-page .org-summary { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.75rem 1.5rem; border-top: 0; padding: 0 0 1.5rem; }
+.organization-page .org-summary .org-warning { flex-basis: 100%; }
+.organization-page .org-summary > p { font-size: 0.9375rem; line-height: 1.7; }
+.organization-page .org-billing { justify-self: start; font-size: 0.9375rem; white-space: nowrap; }
+.organization-page .org-settings { flex: 1; font-size: 0.9375rem; }
+.organization-page .org-settings summary { cursor: pointer; width: fit-content; }
+.organization-page .org-settings form { margin-top: 1rem; max-width: 34rem; }
+.organization-page .org-panel-heading { display: flex; align-items: center; gap: 0.5rem; }
+.organization-page .org-count { padding: 0.0625rem 0.4375rem; border-radius: 0.375rem; background: #2a2b30; color: var(--zinc-300); font-size: 0.875rem; }
+.organization-page .org-row { padding: 0.875rem 0; gap: 0.75rem; }
+.organization-page .org-row:last-child { border-bottom: 0; padding-bottom: 0; }
+.organization-page .org-person { display: flex; align-items: center; gap: 0.75rem; min-width: 0; flex-basis: 12rem; }
+.organization-page .org-person-info { display: grid; gap: 0.1875rem; min-width: 0; }
+.organization-page .org-person-name { font-size: 1rem; color: var(--zinc-200); }
+.organization-page .vault-meta { font-size: 0.9375rem; color: #9799a3; word-break: normal; overflow-wrap: anywhere; }
+.organization-page .org-invite-disclosure summary { cursor: pointer; color: var(--zinc-200); font-size: 1rem; width: fit-content; }
+.organization-page .org-invite-disclosure[open] summary { margin-bottom: 1.25rem; }
+.organization-page .org-role { font-size: 0.9375rem; color: var(--zinc-400); }
+.organization-page .org-form { grid-template-columns: minmax(0, 1fr); gap: 1rem; }
+.organization-page .org-form > .btn { grid-column: 1 / -1; justify-self: start; min-width: 8rem; margin-top: 0.25rem; }
+.organization-page .org-field { min-width: 0; }
+.organization-page .label { font-size: 0.9375rem; line-height: 1.5; }
+.organization-page .org-form > p { line-height: 1.7; font-size: 0.9375rem; padding: 0; max-width: 40rem; }
+.organization-page .input { font-family: inherit; font-size: 1rem; border-radius: 0.5rem; min-height: 2.75rem; background-color: #101114; border-color: #35363d; }
+.organization-page .input:disabled { opacity: 0.65; }
+.organization-page .btn { font-size: 0.9375rem; line-height: 1.5; border-radius: 0.5rem; min-height: 2.75rem; }
+.organization-page :is(a, button, summary, input, select):focus-visible { outline: 2px solid #b2b5cd; outline-offset: 3px; }
+.organization-page .org-list-title { font-size: 0.9375rem; font-weight: 500; padding-top: 1rem; border-top: 1px solid var(--zinc-800); color: var(--zinc-300); }
+.organization-page .org-vaults { display: grid; gap: 0.875rem; padding-top: 1.5rem; border-top: 1px solid #2a2b30; }
+.organization-page .org-section-title { color: var(--zinc-200); font-size: 1.25rem; font-weight: 600; margin-top: 0.25rem; }
+.organization-page .org-help { font-size: 0.9375rem; line-height: 1.75; color: #9799a3; max-width: 55rem; margin-bottom: 0.375rem; }
+.organization-page .org-vault { gap: 0.375rem; padding: 1rem 1.25rem; border: 1px solid #2a2b30; border-radius: 0.5rem; background: #141518; }
+.organization-page .org-vault > .org-inline { margin-top: 1rem; }
+.organization-page #invite-result { margin-top: 1rem; }
+@media (max-width: 480px) {
+ .organization-page { padding-inline: 1rem; padding-top: 1rem; }
+ .organization-page .organization-topbar { margin-bottom: 2rem; }
+ .organization-page .org-vault { padding: 1rem; }
+ .organization-page .org-toolbar .label { width: 100%; }
+ .organization-page .org-toolbar .input { flex: 1; }
+ .organization-page #vaults-link { width: 100%; margin-left: 0; }
+ .organization-page .org-form { grid-template-columns: 1fr; }
+ .organization-page .org-row > .input { max-width: 100%; }
+ .organization-page .org-inline > .input { width: 100%; }
+}
diff --git a/apps/api/public/vault-crypto.js b/apps/api/public/vault-crypto.js
index 8318572f..5d769f30 100644
--- a/apps/api/public/vault-crypto.js
+++ b/apps/api/public/vault-crypto.js
@@ -1,4 +1,4 @@
-"use strict";var synchVaultCrypto=(()=>{var EA=Object.create;var x=Object.defineProperty;var fA=Object.getOwnPropertyDescriptor;var DA=Object.getOwnPropertyNames;var FA=Object.getPrototypeOf,cA=Object.prototype.hasOwnProperty;var kA=(I,i)=>()=>{try{return i||I((i={exports:{}}).exports,i),i.exports}catch(r){throw i=0,r}},pA=(I,i)=>{for(var r in i)x(I,r,{get:i[r],enumerable:!0})},rA=(I,i,r,a)=>{if(i&&typeof i=="object"||typeof i=="function")for(let F of DA(i))!cA.call(I,F)&&F!==r&&x(I,F,{get:()=>i[F],enumerable:!(a=fA(i,F))||a.enumerable});return I};var SA=(I,i,r)=>(r=I!=null?EA(FA(I)):{},rA(i||!I||!I.__esModule?x(r,"default",{value:I,enumerable:!0}):r,I)),UA=I=>rA(x({},"__esModule",{value:!0}),I);var BA=kA((v,oA)=>{(function(I,i){typeof v=="object"&&typeof oA<"u"?i(v):typeof define=="function"&&define.amd?define(["exports"],i):i((I=typeof globalThis<"u"?globalThis:I||self).hashwasm=I.hashwasm||{})})(v,(function(I){"use strict";function i(A,C,g,e){return new(g||(g=Promise))((function(t,o){function h(s){try{B(e.next(s))}catch(D){o(D)}}function n(s){try{B(e.throw(s))}catch(D){o(D)}}function B(s){var D;s.done?t(s.value):(D=s.value,D instanceof g?D:new g((function(f){f(D)}))).then(h,n)}B((e=e.apply(A,C||[])).next())}))}typeof SuppressedError=="function"&&SuppressedError;var r,a={name:"argon2",data:"AGFzbQEAAAABKQVgAX8Bf2AAAX9gEH9/f39/f39/f39/f39/f38AYAR/f39/AGACf38AAwYFAAECAwQFBgEBAoCAAgYIAX8BQZCoBAsHQQQGbWVtb3J5AgASSGFzaF9TZXRNZW1vcnlTaXplAAAOSGFzaF9HZXRCdWZmZXIAAQ5IYXNoX0NhbGN1bGF0ZQAECvEyBVgBAn9BACEBAkAgAEEAKAKICCICRg0AAkAgACACayIAQRB2IABBgIB8cSAASWoiAEAAQX9HDQBB/wHADwtBACEBQQBBACkDiAggAEEQdK18NwOICAsgAcALcAECfwJAQQAoAoAIIgANAEEAPwBBEHQiADYCgAhBACgCiAgiAUGAgCBGDQACQEGAgCAgAWsiAEEQdiAAQYCAfHEgAElqIgBAAEF/Rw0AQQAPC0EAQQApA4gIIABBEHStfDcDiAhBACgCgAghAAsgAAvcDgECfiAAIAQpAwAiECAAKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAMIBAgDCkDAIVCIIkiEDcDACAIIBAgCCkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgBCAQIAQpAwCFQiiJIhA3AwAgACAQIAApAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAwgECAMKQMAhUIwiSIQNwMAIAggECAIKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAEIBAgBCkDAIVCAYk3AwAgASAFKQMAIhAgASkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDSAQIA0pAwCFQiCJIhA3AwAgCSAQIAkpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAUgECAFKQMAhUIoiSIQNwMAIAEgECABKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACANIBAgDSkDAIVCMIkiEDcDACAJIBAgCSkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBSAQIAUpAwCFQgGJNwMAIAIgBikDACIQIAIpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIA4gECAOKQMAhUIgiSIQNwMAIAogECAKKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAGIBAgBikDAIVCKIkiEDcDACACIBAgAikDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgDiAQIA4pAwCFQjCJIhA3AwAgCiAQIAopAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAYgECAGKQMAhUIBiTcDACADIAcpAwAiECADKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAPIBAgDykDAIVCIIkiEDcDACALIBAgCykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgByAQIAcpAwCFQiiJIhA3AwAgAyAQIAMpAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIA8gECAPKQMAhUIwiSIQNwMAIAsgECALKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgACAFKQMAIhAgACkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDyAQIA8pAwCFQiCJIhA3AwAgCiAQIAopAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAUgECAFKQMAhUIoiSIQNwMAIAAgECAAKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAPIBAgDykDAIVCMIkiEDcDACAKIBAgCikDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBSAQIAUpAwCFQgGJNwMAIAEgBikDACIQIAEpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAwgECAMKQMAhUIgiSIQNwMAIAsgECALKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAGIBAgBikDAIVCKIkiEDcDACABIBAgASkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgDCAQIAwpAwCFQjCJIhA3AwAgCyAQIAspAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAYgECAGKQMAhUIBiTcDACACIAcpAwAiECACKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACANIBAgDSkDAIVCIIkiEDcDACAIIBAgCCkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgByAQIAcpAwCFQiiJIhA3AwAgAiAQIAIpAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIA0gECANKQMAhUIwiSIQNwMAIAggECAIKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgAyAEKQMAIhAgAykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDiAQIA4pAwCFQiCJIhA3AwAgCSAQIAkpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAQgECAEKQMAhUIoiSIQNwMAIAMgECADKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAOIBAgDikDAIVCMIkiEDcDACAJIBAgCSkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBCAQIAQpAwCFQgGJNwMAC98aAQN/QQAhBEEAIAIpAwAgASkDAIU3A5AIQQAgAikDCCABKQMIhTcDmAhBACACKQMQIAEpAxCFNwOgCEEAIAIpAxggASkDGIU3A6gIQQAgAikDICABKQMghTcDsAhBACACKQMoIAEpAyiFNwO4CEEAIAIpAzAgASkDMIU3A8AIQQAgAikDOCABKQM4hTcDyAhBACACKQNAIAEpA0CFNwPQCEEAIAIpA0ggASkDSIU3A9gIQQAgAikDUCABKQNQhTcD4AhBACACKQNYIAEpA1iFNwPoCEEAIAIpA2AgASkDYIU3A/AIQQAgAikDaCABKQNohTcD+AhBACACKQNwIAEpA3CFNwOACUEAIAIpA3ggASkDeIU3A4gJQQAgAikDgAEgASkDgAGFNwOQCUEAIAIpA4gBIAEpA4gBhTcDmAlBACACKQOQASABKQOQAYU3A6AJQQAgAikDmAEgASkDmAGFNwOoCUEAIAIpA6ABIAEpA6ABhTcDsAlBACACKQOoASABKQOoAYU3A7gJQQAgAikDsAEgASkDsAGFNwPACUEAIAIpA7gBIAEpA7gBhTcDyAlBACACKQPAASABKQPAAYU3A9AJQQAgAikDyAEgASkD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",hash:"e4cdc523"};class F{constructor(){this.mutex=Promise.resolve()}lock(){let C=()=>{};return this.mutex=this.mutex.then((()=>new Promise(C))),new Promise((g=>{C=g}))}dispatch(C){return i(this,void 0,void 0,(function*(){let g=yield this.lock();try{return yield Promise.resolve(C())}finally{g()}}))}}let J=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,d=(r=J.Buffer)!==null&&r!==void 0?r:null,Y=J.TextEncoder?new J.TextEncoder:null;function z(A,C){return(15&A)+(A>>6|A>>3&8)<<4|(15&C)+(C>>6|C>>3&8)}function $(A,C){let g=C.length>>1;for(let e=0;e>>4;A[e++]=o>9?o+AA:o+IA,o=15&C[t],A[e++]=o>9?o+AA:o+IA}return String.fromCharCode.apply(null,A)}let l=d!==null?A=>{if(typeof A=="string"){let C=d.from(A,"utf8");return new Uint8Array(C.buffer,C.byteOffset,C.length)}if(d.isBuffer(A))return new Uint8Array(A.buffer,A.byteOffset,A.length);if(ArrayBuffer.isView(A))return new Uint8Array(A.buffer,A.byteOffset,A.byteLength);throw new Error("Invalid data type!")}:A=>{if(typeof A=="string")return Y.encode(A);if(ArrayBuffer.isView(A))return new Uint8Array(A.buffer,A.byteOffset,A.byteLength);throw new Error("Invalid data type!")},U="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",N=new Uint8Array(256);for(let A=0;A>18&63)+U.charAt(n>>12&63)+U.charAt(n>>6&63)+U.charAt(63&n);t.push(B)}if(e===1){let h=A[g-1],n=U.charAt(h>>2),B=U.charAt(h<<4&63);t.push(`${n}${B}`),C&&t.push("==")}else if(e===2){let h=(A[g-2]<<8)+A[g-1],n=U.charAt(h>>10),B=U.charAt(h>>4&63),s=U.charAt(h<<2&63);t.push(`${n}${B}${s}`),C&&t.push("=")}return t.join("")}function gA(A){let C=Math.floor(.75*A.length),g=A.length;return A[g-1]==="="&&(C-=1,A[g-2]==="="&&(C-=1)),C}function CA(A){let C=gA(A),g=A.length,e=new Uint8Array(C),t=0;for(let o=0;o>4,t+=1,e[t]=(15&n)<<4|B>>2,t+=1,e[t]=(3&B)<<6|63&s,t+=1}return e}let L=16384,aA=new F,Z=new Map;function eA(A,C){return i(this,void 0,void 0,(function*(){let g=null,e=null,t=!1;if(typeof WebAssembly>"u")throw new Error("WebAssembly is not supported in this environment!");let o=()=>new DataView(g.exports.memory.buffer).getUint32(g.exports.STATE_SIZE,!0),h=aA.dispatch((()=>i(this,void 0,void 0,(function*(){if(!Z.has(A.name)){let w=CA(A.data),E=WebAssembly.compile(w);Z.set(A.name,E)}let Q=yield Z.get(A.name);g=yield WebAssembly.instantiate(Q,{})})))),n=(Q=null)=>{t=!0,g.exports.Hash_Init(Q)},B=Q=>{if(!t)throw new Error("update() called before init()");(w=>{let E=0;for(;E{if(!t)throw new Error("digest() called before init()");return t=!1,g.exports.Hash_Final(w),Q==="binary"?e.slice(0,C):T(s,e,C)},f=Q=>typeof Q=="string"?Q.length<4096:Q.byteLength!0;break;case"blake2b":case"blake2s":k=(Q,w)=>w<=512&&f(Q);break;case"blake3":k=(Q,w)=>w===0&&f(Q);break;case"xxhash64":case"xxhash3":case"xxhash128":case"crc64":k=()=>!1}return yield i(this,void 0,void 0,(function*(){g||(yield h);let Q=g.exports.Hash_GetBuffer(),w=g.exports.memory.buffer;e=new Uint8Array(w,Q,L)})),{getMemory:()=>e,writeMemory:(Q,w=0)=>{e.set(Q,w)},getExports:()=>g.exports,setMemorySize:Q=>{g.exports.Hash_SetMemorySize(Q);let w=g.exports.Hash_GetBuffer(),E=g.exports.memory.buffer;e=new Uint8Array(E,w,Q)},init:n,update:B,digest:D,save:()=>{if(!t)throw new Error("save() can only be called after init() and before digest()");let Q=g.exports.Hash_GetState(),w=o(),E=g.exports.memory.buffer,c=new Uint8Array(E,Q,w),G=new Uint8Array(4+w);return $(G,A.hash),G.set(c,4),G},load:Q=>{if(!(Q instanceof Uint8Array))throw new Error("load() expects an Uint8Array generated by save()");let w=g.exports.Hash_GetState(),E=o(),c=4+E,G=g.exports.memory.buffer;if(Q.length!==c)throw new Error(`Bad state length (expected ${c} bytes, got ${Q.length})`);if(!(function(p,S){if(p.length!==2*S.length)return!1;for(let y=0;y{if(!k(Q,w))return n(w),B(Q),D("hex",E);let c=l(Q);return e.set(c),g.exports.Hash_Calculate(c.length,w,E),T(s,e,C)},hashLength:C}}))}var sA={name:"blake2b",data:"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",hash:"c6f286e6"};function tA(A){return!Number.isInteger(A)||A<8||A>512||A%8!=0?new Error("Invalid variant! Valid values: 8, 16, ..., 512"):null}function W(A=512,C=null){if(tA(A))return Promise.reject(tA(A));let g=null,e=A;if(C!==null){if(g=l(C),g.length>64)return Promise.reject(new Error("Max key length is 64 bytes"));t=A,o=g.length,e=t|o<<16}var t,o;let h=A/8;return eA(sA,h).then((n=>{e>512&&n.writeMemory(g),n.init(e);let B={init:e>512?()=>(n.writeMemory(g),n.init(e),B):()=>(n.init(e),B),update:s=>(n.update(s),B),digest:s=>n.digest(s),save:()=>n.save(),load:s=>(n.load(s),B),blockSize:128,digestSize:h};return B}))}new F;let QA=new DataView(new ArrayBuffer(4));function u(A){return QA.setInt32(0,A,!0),new Uint8Array(QA.buffer)}function q(A,C,g){return i(this,void 0,void 0,(function*(){if(g<=64){let B=yield W(8*g);return B.update(u(g)),B.update(C),B.digest("binary")}let e=Math.ceil(g/32)-2,t=new Uint8Array(g);A.init(),A.update(u(g)),A.update(C);let o=A.digest("binary");t.set(o.subarray(0,32),0);for(let B=1;B{var C;if(!A||typeof A!="object")throw new Error("Invalid options parameter. It requires an object.");if(!A.password)throw new Error("Password must be specified");if(A.password=l(A.password),A.password.length<1)throw new Error("Password must be specified");if(!A.salt)throw new Error("Salt must be specified");if(A.salt=l(A.salt),A.salt.length<8)throw new Error("Salt should be at least 8 bytes long");if(A.secret=l((C=A.secret)!==null&&C!==void 0?C:""),!Number.isInteger(A.iterations)||A.iterations<1)throw new Error("Iterations should be a positive number");if(!Number.isInteger(A.parallelism)||A.parallelism<1)throw new Error("Parallelism should be a positive number");if(!Number.isInteger(A.hashLength)||A.hashLength<4)throw new Error("Hash length should be at least 4 bytes.");if(!Number.isInteger(A.memorySize))throw new Error("Memory size should be specified.");if(A.memorySize<8*A.parallelism)throw new Error("Memory size should be at least 8 * parallelism.");if(A.outputType===void 0&&(A.outputType="hex"),!["hex","binary","encoded"].includes(A.outputType))throw new Error(`Insupported output type ${A.outputType}. Valid values: ['hex', 'binary', 'encoded']`)};I.argon2Verify=function(A){return i(this,void 0,void 0,(function*(){(e=>{if(!e||typeof e!="object")throw new Error("Invalid options parameter. It requires an object.");if(e.hash===void 0||typeof e.hash!="string")throw new Error("Hash should be specified")})(A);let C=((e,t,o)=>{let h=t.match(/^\$argon2(id|i|d)\$v=([0-9]+)\$((?:[mtp]=[0-9]+,){2}[mtp]=[0-9]+)\$([A-Za-z0-9+/]+)\$([A-Za-z0-9+/]+)$/);if(!h)throw new Error("Invalid hash");let[,n,B,s,D,f]=h;if(B!=="19")throw new Error(`Unsupported version: ${B}`);let k={},Q={m:"memorySize",p:"parallelism",t:"iterations"};for(let w of s.split(",")){let[E,c]=w.split("=");k[Q[E]]=Number(c)}return Object.assign(Object.assign({},k),{password:e,secret:o,hashType:n,salt:CA(D),hashLength:gA(f),outputType:"encoded"})})(A.password,A.hash,A.secret);M(C);let g=A.hash.lastIndexOf("$")+1;return(yield b(C)).substring(g)===A.hash.substring(g)}))},I.argon2d=function(A){return i(this,void 0,void 0,(function*(){return M(A),b(Object.assign(Object.assign({},A),{hashType:"d"}))}))},I.argon2i=function(A){return i(this,void 0,void 0,(function*(){return M(A),b(Object.assign(Object.assign({},A),{hashType:"i"}))}))},I.argon2id=function(A){return i(this,void 0,void 0,(function*(){return M(A),b(Object.assign(Object.assign({},A),{hashType:"id"}))}))}}))});var MA={};pA(MA,{VaultPasswordError:()=>P,createArgon2idMetadata:()=>j,createPasswordWrappedRemoteVaultKey:()=>KA,decodeBase64:()=>H,deriveWrapKey:()=>R,encodeBase64:()=>V,randomBytes:()=>m,toArrayBuffer:()=>K,unwrapRemoteVaultKeyWithPassword:()=>JA,validateVaultPassword:()=>NA});function m(I){return crypto.getRandomValues(new Uint8Array(I))}function V(I){let i=[];for(let r=0;rSA(BA(),1)),a=r.default?.argon2id??r["module.exports"]?.argon2id;if(!a)throw new Error("argon2id module failed to load");let F=await a({password:new TextEncoder().encode(I),salt:H(i.salt),iterations:i.iterations,parallelism:i.parallelism,memorySize:i.memoryKiB,hashLength:lA,outputType:"binary"});return await crypto.subtle.importKey("raw",K(F),{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}var nA="aes-256-gcm",hA=1,uA=1,dA=32,GA=12,P=class extends Error{constructor(r,a){super(a);this.code=r;this.name="VaultPasswordError"}};async function KA(I,i={}){let r=wA(I),a=m(dA),F=j(i.kdfOverrides),J=await R(r,F),d=m(GA),Y=await VA(J,a,d);return{remoteVaultKey:a,envelope:{version:hA,keyVersion:uA,kdf:F,wrap:{algorithm:nA,nonce:V(d),ciphertext:V(Y)}}}}async function JA(I,i){let r=wA(I);HA(i);let a=H(i.kdf.salt),F=H(i.wrap.nonce),J=H(i.wrap.ciphertext),d=await R(r,{...i.kdf,salt:V(a)}),Y=await crypto.subtle.decrypt({name:"AES-GCM",iv:K(F)},d,K(J));return new Uint8Array(Y)}async function VA(I,i,r){let a=await crypto.subtle.encrypt({name:"AES-GCM",iv:K(r)},I,K(i));return new Uint8Array(a)}function HA(I){if(I.version!==hA)throw new Error(`unsupported wrapper version: ${I.version}`);if(I.wrap.algorithm!==nA)throw new Error(`unsupported wrap algorithm: ${I.wrap.algorithm}`)}function wA(I){if(!I)throw new P("required","Password is required.");if(I!==I.trim())throw new P("outer_spaces","Password cannot start or end with spaces.");return I}var mA=new Set(["123456","123456789","1234567890","password","password1","password123","qwerty","qwerty123","letmein","admin","welcome","iloveyou","vault","vaultpassword","synch","synchpassword","obsidian","obsidianvault","obsidianvaultpassword","synchvaultpassword"]),YA=["password","qwerty","letmein","admin","welcome","iloveyou","vault","synch","obsidian"];function NA(I){return I?I!==I.trim()?{ok:!1,code:"outer_spaces",message:"Password cannot start or end with spaces."}:I.length<12?{ok:!1,code:"min_length",count:12,message:"Password must be at least 12 characters."}:I.length>256?{ok:!1,code:"max_length",count:256,message:"Password must be 256 characters or fewer."}:PA(I)?{ok:!1,code:"too_weak",message:"Password is too easy to guess. Use a longer passphrase."}:OA(I)?{ok:!1,code:"repeated_character",message:"Password cannot be one repeated character."}:bA(I)?{ok:!1,code:"simple_sequence",message:"Password cannot be a simple sequence."}:{ok:!0}:{ok:!1,code:"required",message:"Password is required."}}function OA(I){return new Set(I.toLowerCase()).size===1}function PA(I){let i=I.toLowerCase().replace(/[^a-z0-9]/g,"");if(mA.has(i))return!0;for(let r of YA)i=i.split(r).join("");return i===""||/^[0-9]+$/.test(i)}function bA(I){if(!/^[a-z]+$/i.test(I)&&!/^[0-9]+$/.test(I))return!1;let i=I.toLowerCase(),r=i.charCodeAt(1)-i.charCodeAt(0);if(r!==1&&r!==-1)return!1;for(let a=1;a{var kA=Object.create;var v=Object.defineProperty;var uA=Object.getOwnPropertyDescriptor;var SA=Object.getOwnPropertyNames;var lA=Object.getPrototypeOf,dA=Object.prototype.hasOwnProperty;var UA=(I,i)=>()=>{try{return i||I((i={exports:{}}).exports,i),i.exports}catch(g){throw i=0,g}},GA=(I,i)=>{for(var g in i)v(I,g,{get:i[g],enumerable:!0})},BA=(I,i,g,B)=>{if(i&&typeof i=="object"||typeof i=="function")for(let E of SA(i))!dA.call(I,E)&&E!==g&&v(I,E,{get:()=>i[E],enumerable:!(B=uA(i,E))||B.enumerable});return I};var KA=(I,i,g)=>(g=I!=null?kA(lA(I)):{},BA(i||!I||!I.__esModule?v(g,"default",{value:I,enumerable:!0}):g,I)),mA=I=>BA(v({},"__esModule",{value:!0}),I);var sA=UA((X,hA)=>{(function(I,i){typeof X=="object"&&typeof hA<"u"?i(X):typeof define=="function"&&define.amd?define(["exports"],i):i((I=typeof globalThis<"u"?globalThis:I||self).hashwasm=I.hashwasm||{})})(X,(function(I){"use strict";function i(A,t,e,r){return new(e||(e=Promise))((function(C,o){function h(w){try{Q(r.next(w))}catch(D){o(D)}}function a(w){try{Q(r.throw(w))}catch(D){o(D)}}function Q(w){var D;w.done?C(w.value):(D=w.value,D instanceof e?D:new e((function(c){c(D)}))).then(h,a)}Q((r=r.apply(A,t||[])).next())}))}typeof SuppressedError=="function"&&SuppressedError;var g,B={name:"argon2",data:"AGFzbQEAAAABKQVgAX8Bf2AAAX9gEH9/f39/f39/f39/f39/f38AYAR/f39/AGACf38AAwYFAAECAwQFBgEBAoCAAgYIAX8BQZCoBAsHQQQGbWVtb3J5AgASSGFzaF9TZXRNZW1vcnlTaXplAAAOSGFzaF9HZXRCdWZmZXIAAQ5IYXNoX0NhbGN1bGF0ZQAECvEyBVgBAn9BACEBAkAgAEEAKAKICCICRg0AAkAgACACayIAQRB2IABBgIB8cSAASWoiAEAAQX9HDQBB/wHADwtBACEBQQBBACkDiAggAEEQdK18NwOICAsgAcALcAECfwJAQQAoAoAIIgANAEEAPwBBEHQiADYCgAhBACgCiAgiAUGAgCBGDQACQEGAgCAgAWsiAEEQdiAAQYCAfHEgAElqIgBAAEF/Rw0AQQAPC0EAQQApA4gIIABBEHStfDcDiAhBACgCgAghAAsgAAvcDgECfiAAIAQpAwAiECAAKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAMIBAgDCkDAIVCIIkiEDcDACAIIBAgCCkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgBCAQIAQpAwCFQiiJIhA3AwAgACAQIAApAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAwgECAMKQMAhUIwiSIQNwMAIAggECAIKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAEIBAgBCkDAIVCAYk3AwAgASAFKQMAIhAgASkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDSAQIA0pAwCFQiCJIhA3AwAgCSAQIAkpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAUgECAFKQMAhUIoiSIQNwMAIAEgECABKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACANIBAgDSkDAIVCMIkiEDcDACAJIBAgCSkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBSAQIAUpAwCFQgGJNwMAIAIgBikDACIQIAIpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIA4gECAOKQMAhUIgiSIQNwMAIAogECAKKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAGIBAgBikDAIVCKIkiEDcDACACIBAgAikDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgDiAQIA4pAwCFQjCJIhA3AwAgCiAQIAopAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAYgECAGKQMAhUIBiTcDACADIAcpAwAiECADKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAPIBAgDykDAIVCIIkiEDcDACALIBAgCykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgByAQIAcpAwCFQiiJIhA3AwAgAyAQIAMpAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIA8gECAPKQMAhUIwiSIQNwMAIAsgECALKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgACAFKQMAIhAgACkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDyAQIA8pAwCFQiCJIhA3AwAgCiAQIAopAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAUgECAFKQMAhUIoiSIQNwMAIAAgECAAKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAPIBAgDykDAIVCMIkiEDcDACAKIBAgCikDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBSAQIAUpAwCFQgGJNwMAIAEgBikDACIQIAEpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAwgECAMKQMAhUIgiSIQNwMAIAsgECALKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAGIBAgBikDAIVCKIkiEDcDACABIBAgASkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgDCAQIAwpAwCFQjCJIhA3AwAgCyAQIAspAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAYgECAGKQMAhUIBiTcDACACIAcpAwAiECACKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACANIBAgDSkDAIVCIIkiEDcDACAIIBAgCCkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgByAQIAcpAwCFQiiJIhA3AwAgAiAQIAIpAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIA0gECANKQMAhUIwiSIQNwMAIAggECAIKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgAyAEKQMAIhAgAykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDiAQIA4pAwCFQiCJIhA3AwAgCSAQIAkpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAQgECAEKQMAhUIoiSIQNwMAIAMgECADKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAOIBAgDikDAIVCMIkiEDcDACAJIBAgCSkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBCAQIAQpAwCFQgGJNwMAC98aAQN/QQAhBEEAIAIpAwAgASkDAIU3A5AIQQAgAikDCCABKQMIhTcDmAhBACACKQMQIAEpAxCFNwOgCEEAIAIpAxggASkDGIU3A6gIQQAgAikDICABKQMghTcDsAhBACACKQMoIAEpAyiFNwO4CEEAIAIpAzAgASkDMIU3A8AIQQAgAikDOCABKQM4hTcDyAhBACACKQNAIAEpA0CFNwPQCEEAIAIpA0ggASkDSIU3A9gIQQAgAikDUCABKQNQhTcD4AhBACACKQNYIAEpA1iFNwPoCEEAIAIpA2AgASkDYIU3A/AIQQAgAikDaCABKQNohTcD+AhBACACKQNwIAEpA3CFNwOACUEAIAIpA3ggASkDeIU3A4gJQQAgAikDgAEgASkDgAGFNwOQCUEAIAIpA4gBIAEpA4gBhTcDmAlBACACKQOQASABKQOQAYU3A6AJQQAgAikDmAEgASkDmAGFNwOoCUEAIAIpA6ABIAEpA6ABhTcDsAlBACACKQOoASABKQOoAYU3A7gJQQAgAikDsAEgASkDsAGFNwPACUEAIAIpA7gBIAEpA7gBhTcDyAlBACACKQPAASABKQPAAYU3A9AJQQAgAikDyAEgASkD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",hash:"e4cdc523"};class E{constructor(){this.mutex=Promise.resolve()}lock(){let t=()=>{};return this.mutex=this.mutex.then((()=>new Promise(t))),new Promise((e=>{t=e}))}dispatch(t){return i(this,void 0,void 0,(function*(){let e=yield this.lock();try{return yield Promise.resolve(t())}finally{e()}}))}}let U=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,K=(g=U.Buffer)!==null&&g!==void 0?g:null,T=U.TextEncoder?new U.TextEncoder:null;function P(A,t){return(15&A)+(A>>6|A>>3&8)<<4|(15&t)+(t>>6|t>>3&8)}function eA(A,t){let e=t.length>>1;for(let r=0;r>>4;A[r++]=o>9?o+gA:o+tA,o=15&t[C],A[r++]=o>9?o+gA:o+tA}return String.fromCharCode.apply(null,A)}let m=K!==null?A=>{if(typeof A=="string"){let t=K.from(A,"utf8");return new Uint8Array(t.buffer,t.byteOffset,t.length)}if(K.isBuffer(A))return new Uint8Array(A.buffer,A.byteOffset,A.length);if(ArrayBuffer.isView(A))return new Uint8Array(A.buffer,A.byteOffset,A.byteLength);throw new Error("Invalid data type!")}:A=>{if(typeof A=="string")return T.encode(A);if(ArrayBuffer.isView(A))return new Uint8Array(A.buffer,A.byteOffset,A.byteLength);throw new Error("Invalid data type!")},l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",b=new Uint8Array(256);for(let A=0;A>18&63)+l.charAt(a>>12&63)+l.charAt(a>>6&63)+l.charAt(63&a);C.push(Q)}if(r===1){let h=A[e-1],a=l.charAt(h>>2),Q=l.charAt(h<<4&63);C.push(`${a}${Q}`),t&&C.push("==")}else if(r===2){let h=(A[e-2]<<8)+A[e-1],a=l.charAt(h>>10),Q=l.charAt(h>>4&63),w=l.charAt(h<<2&63);C.push(`${a}${Q}${w}`),t&&C.push("=")}return C.join("")}function CA(A){let t=Math.floor(.75*A.length),e=A.length;return A[e-1]==="="&&(t-=1,A[e-2]==="="&&(t-=1)),t}function nA(A){let t=CA(A),e=A.length,r=new Uint8Array(t),C=0;for(let o=0;o>4,C+=1,r[C]=(15&a)<<4|Q>>2,C+=1,r[C]=(3&Q)<<6|63&w,C+=1}return r}let W=16384,FA=new E,Z=new Map;function oA(A,t){return i(this,void 0,void 0,(function*(){let e=null,r=null,C=!1;if(typeof WebAssembly>"u")throw new Error("WebAssembly is not supported in this environment!");let o=()=>new DataView(e.exports.memory.buffer).getUint32(e.exports.STATE_SIZE,!0),h=FA.dispatch((()=>i(this,void 0,void 0,(function*(){if(!Z.has(A.name)){let s=nA(A.data),f=WebAssembly.compile(s);Z.set(A.name,f)}let n=yield Z.get(A.name);e=yield WebAssembly.instantiate(n,{})})))),a=(n=null)=>{C=!0,e.exports.Hash_Init(n)},Q=n=>{if(!C)throw new Error("update() called before init()");(s=>{let f=0;for(;f{if(!C)throw new Error("digest() called before init()");return C=!1,e.exports.Hash_Final(s),n==="binary"?r.slice(0,t):L(w,r,t)},c=n=>typeof n=="string"?n.length<4096:n.byteLength!0;break;case"blake2b":case"blake2s":k=(n,s)=>s<=512&&c(n);break;case"blake3":k=(n,s)=>s===0&&c(n);break;case"xxhash64":case"xxhash3":case"xxhash128":case"crc64":k=()=>!1}return yield i(this,void 0,void 0,(function*(){e||(yield h);let n=e.exports.Hash_GetBuffer(),s=e.exports.memory.buffer;r=new Uint8Array(s,n,W)})),{getMemory:()=>r,writeMemory:(n,s=0)=>{r.set(n,s)},getExports:()=>e.exports,setMemorySize:n=>{e.exports.Hash_SetMemorySize(n);let s=e.exports.Hash_GetBuffer(),f=e.exports.memory.buffer;r=new Uint8Array(f,s,n)},init:a,update:Q,digest:D,save:()=>{if(!C)throw new Error("save() can only be called after init() and before digest()");let n=e.exports.Hash_GetState(),s=o(),f=e.exports.memory.buffer,p=new Uint8Array(f,n,s),J=new Uint8Array(4+s);return eA(J,A.hash),J.set(p,4),J},load:n=>{if(!(n instanceof Uint8Array))throw new Error("load() expects an Uint8Array generated by save()");let s=e.exports.Hash_GetState(),f=o(),p=4+f,J=e.exports.memory.buffer;if(n.length!==p)throw new Error(`Bad state length (expected ${p} bytes, got ${n.length})`);if(!(function(u,S){if(u.length!==2*S.length)return!1;for(let G=0;G{if(!k(n,s))return a(s),Q(n),D("hex",f);let p=m(n);return r.set(p),e.exports.Hash_Calculate(p.length,s,f),L(w,r,t)},hashLength:t}}))}var yA={name:"blake2b",data:"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",hash:"c6f286e6"};function QA(A){return!Number.isInteger(A)||A<8||A>512||A%8!=0?new Error("Invalid variant! Valid values: 8, 16, ..., 512"):null}function q(A=512,t=null){if(QA(A))return Promise.reject(QA(A));let e=null,r=A;if(t!==null){if(e=m(t),e.length>64)return Promise.reject(new Error("Max key length is 64 bytes"));C=A,o=e.length,r=C|o<<16}var C,o;let h=A/8;return oA(yA,h).then((a=>{r>512&&a.writeMemory(e),a.init(r);let Q={init:r>512?()=>(a.writeMemory(e),a.init(r),Q):()=>(a.init(r),Q),update:w=>(a.update(w),Q),digest:w=>a.digest(w),save:()=>a.save(),load:w=>(a.load(w),Q),blockSize:128,digestSize:h};return Q}))}new E;let aA=new DataView(new ArrayBuffer(4));function V(A){return aA.setInt32(0,A,!0),new Uint8Array(aA.buffer)}function _(A,t,e){return i(this,void 0,void 0,(function*(){if(e<=64){let Q=yield q(8*e);return Q.update(V(e)),Q.update(t),Q.digest("binary")}let r=Math.ceil(e/32)-2,C=new Uint8Array(e);A.init(),A.update(V(e)),A.update(t);let o=A.digest("binary");C.set(o.subarray(0,32),0);for(let Q=1;Q{var t;if(!A||typeof A!="object")throw new Error("Invalid options parameter. It requires an object.");if(!A.password)throw new Error("Password must be specified");if(A.password=m(A.password),A.password.length<1)throw new Error("Password must be specified");if(!A.salt)throw new Error("Salt must be specified");if(A.salt=m(A.salt),A.salt.length<8)throw new Error("Salt should be at least 8 bytes long");if(A.secret=m((t=A.secret)!==null&&t!==void 0?t:""),!Number.isInteger(A.iterations)||A.iterations<1)throw new Error("Iterations should be a positive number");if(!Number.isInteger(A.parallelism)||A.parallelism<1)throw new Error("Parallelism should be a positive number");if(!Number.isInteger(A.hashLength)||A.hashLength<4)throw new Error("Hash length should be at least 4 bytes.");if(!Number.isInteger(A.memorySize))throw new Error("Memory size should be specified.");if(A.memorySize<8*A.parallelism)throw new Error("Memory size should be at least 8 * parallelism.");if(A.outputType===void 0&&(A.outputType="hex"),!["hex","binary","encoded"].includes(A.outputType))throw new Error(`Insupported output type ${A.outputType}. Valid values: ['hex', 'binary', 'encoded']`)};I.argon2Verify=function(A){return i(this,void 0,void 0,(function*(){(r=>{if(!r||typeof r!="object")throw new Error("Invalid options parameter. It requires an object.");if(r.hash===void 0||typeof r.hash!="string")throw new Error("Hash should be specified")})(A);let t=((r,C,o)=>{let h=C.match(/^\$argon2(id|i|d)\$v=([0-9]+)\$((?:[mtp]=[0-9]+,){2}[mtp]=[0-9]+)\$([A-Za-z0-9+/]+)\$([A-Za-z0-9+/]+)$/);if(!h)throw new Error("Invalid hash");let[,a,Q,w,D,c]=h;if(Q!=="19")throw new Error(`Unsupported version: ${Q}`);let k={},n={m:"memorySize",p:"parallelism",t:"iterations"};for(let s of w.split(",")){let[f,p]=s.split("=");k[n[f]]=Number(p)}return Object.assign(Object.assign({},k),{password:r,secret:o,hashType:a,salt:nA(D),hashLength:CA(c),outputType:"encoded"})})(A.password,A.hash,A.secret);M(t);let e=A.hash.lastIndexOf("$")+1;return(yield O(t)).substring(e)===A.hash.substring(e)}))},I.argon2d=function(A){return i(this,void 0,void 0,(function*(){return M(A),O(Object.assign(Object.assign({},A),{hashType:"d"}))}))},I.argon2i=function(A){return i(this,void 0,void 0,(function*(){return M(A),O(Object.assign(Object.assign({},A),{hashType:"i"}))}))},I.argon2id=function(A){return i(this,void 0,void 0,(function*(){return M(A),O(Object.assign(Object.assign({},A),{hashType:"id"}))}))}}))});var _A={};GA(_A,{VaultPasswordError:()=>N,createArgon2idMetadata:()=>z,createKeyTransferReceiver:()=>TA,createPasswordWrappedRemoteVaultKey:()=>bA,decodeBase64:()=>F,decryptTransferredVaultKey:()=>qA,deriveWrapKey:()=>R,encodeBase64:()=>d,encryptVaultKeyForReceiver:()=>ZA,keyTransferVerificationCode:()=>WA,randomBytes:()=>H,toArrayBuffer:()=>y,unwrapRemoteVaultKeyWithPassword:()=>YA,validateKeyTransferPublicKey:()=>LA,validateVaultPassword:()=>xA,wrapRemoteVaultKeyWithPassword:()=>cA});function H(I){return crypto.getRandomValues(new Uint8Array(I))}function d(I){let i=[];for(let g=0;gKA(sA(),1)),B=g.default?.argon2id??g["module.exports"]?.argon2id;if(!B)throw new Error("argon2id module failed to load");let E=await B({password:new TextEncoder().encode(I),salt:F(i.salt),iterations:i.iterations,parallelism:i.parallelism,memorySize:i.memoryKiB,hashLength:JA,outputType:"binary"});return await crypto.subtle.importKey("raw",y(E),{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}var wA="aes-256-gcm",fA=1,$=1,EA=32,HA=12,N=class extends Error{constructor(g,B){super(B);this.code=g;this.name="VaultPasswordError"}};async function bA(I,i={}){let g=H(EA);return{remoteVaultKey:g,envelope:await cA(I,g,i)}}async function cA(I,i,g={}){if(i.byteLength!==EA)throw new Error("Invalid vault key length");let B=z(g.kdfOverrides),E=await R(DA(I),B),U=H(HA),K=await NA(E,i,U,g.binding);return{version:g.binding?2:fA,keyVersion:$,...g.binding?{binding:g.binding}:{},kdf:B,wrap:{algorithm:wA,nonce:d(U),ciphertext:d(K)}}}async function YA(I,i,g){let B=DA(I);if(PA(i),i.version===2&&(!g||!i.binding||i.binding.vaultId!==g.vaultId||i.binding.userId!==g.userId))throw new Error("Vault password wrapper belongs to a different vault or user");let E=F(i.kdf.salt),U=F(i.wrap.nonce),K=F(i.wrap.ciphertext),T=await R(B,{...i.kdf,salt:d(E)}),P=await crypto.subtle.decrypt({name:"AES-GCM",iv:y(U),...i.version===2?{additionalData:pA(i.binding)}:{}},T,y(K));return new Uint8Array(P)}async function NA(I,i,g,B){let E=await crypto.subtle.encrypt({name:"AES-GCM",iv:y(g),...B?{additionalData:pA(B)}:{}},I,y(i));return new Uint8Array(E)}function PA(I){if(I.version!==fA&&I.version!==2)throw new Error(`unsupported wrapper version: ${I.version}`);if(I.keyVersion!==$||I.version===1&&I.binding||I.version===2&&(!I.binding?.userId||!I.binding.vaultId))throw new Error("Invalid password wrapper binding or key version");if(I.wrap.algorithm!==wA)throw new Error(`unsupported wrap algorithm: ${I.wrap.algorithm}`)}function DA(I){if(!I)throw new N("required","Password is required.");if(I!==I.trim())throw new N("outer_spaces","Password cannot start or end with spaces.");return I}function pA(I){return new Uint8Array(new TextEncoder().encode(JSON.stringify(["synch.password-wrapper",2,I.vaultId,I.userId,$])))}var OA=new Set(["123456","123456789","1234567890","password","password1","password123","qwerty","qwerty123","letmein","admin","welcome","iloveyou","vault","vaultpassword","synch","synchpassword","obsidian","obsidianvault","obsidianvaultpassword","synchvaultpassword"]),MA=["password","qwerty","letmein","admin","welcome","iloveyou","vault","synch","obsidian"];function xA(I){return I?I!==I.trim()?{ok:!1,code:"outer_spaces",message:"Password cannot start or end with spaces."}:I.length<12?{ok:!1,code:"min_length",count:12,message:"Password must be at least 12 characters."}:I.length>256?{ok:!1,code:"max_length",count:256,message:"Password must be 256 characters or fewer."}:XA(I)?{ok:!1,code:"too_weak",message:"Password is too easy to guess. Use a longer passphrase."}:vA(I)?{ok:!1,code:"repeated_character",message:"Password cannot be one repeated character."}:RA(I)?{ok:!1,code:"simple_sequence",message:"Password cannot be a simple sequence."}:{ok:!0}:{ok:!1,code:"required",message:"Password is required."}}function vA(I){return new Set(I.toLowerCase()).size===1}function XA(I){let i=I.toLowerCase().replace(/[^a-z0-9]/g,"");if(OA.has(i))return!0;for(let g of MA)i=i.split(g).join("");return i===""||/^[0-9]+$/.test(i)}function RA(I){if(!/^[a-z]+$/i.test(I)&&!/^[0-9]+$/.test(I))return!1;let i=I.toLowerCase(),g=i.charCodeAt(1)-i.charCodeAt(0);if(g!==1&&g!==-1)return!1;for(let B=1;BK.toString(16).padStart(2,"0")).join("").match(/.{4}/g).join("-")}async function ZA(I,i,g){if(I.byteLength!==32)throw new Error("Invalid vault key length");let B=await crypto.subtle.encrypt({name:"RSA-OAEP",label:iA(g)},await IA(i),y(I));return{version:1,algorithm:"rsa-oaep-sha256",ciphertext:d(new Uint8Array(B))}}async function qA(I,i,g){if(I.version!==1||I.algorithm!=="rsa-oaep-sha256"||F(I.ciphertext).length!==384)throw new Error("Invalid key transfer envelope");let B=await crypto.subtle.importKey("pkcs8",y(F(i)),AA,!1,["decrypt"]),E=new Uint8Array(await crypto.subtle.decrypt({name:"RSA-OAEP",label:iA(g)},B,y(F(I.ciphertext))));if(E.byteLength!==32)throw new Error("Invalid transferred key length");return E}return mA(_A);})();
/*! Bundled license information:
hash-wasm/dist/argon2.umd.min.js:
diff --git a/apps/api/public/vaults.html b/apps/api/public/vaults.html
index 882d44e1..4653fd70 100644
--- a/apps/api/public/vaults.html
+++ b/apps/api/public/vaults.html
@@ -7,6 +7,7 @@
+
@@ -28,6 +29,7 @@
Remote vaults
+