From 13f09cca65f11f6c972c52fffab5d6b58e776643 Mon Sep 17 00:00:00 2001 From: ingalls Date: Wed, 26 Jun 2024 13:17:46 -0600 Subject: [PATCH 01/19] Add Video Lease --- api/lib/schema.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/api/lib/schema.ts b/api/lib/schema.ts index 471308508..46db34418 100644 --- a/api/lib/schema.ts +++ b/api/lib/schema.ts @@ -51,6 +51,15 @@ export const ProfileChat = pgTable('profile_chats', { message: text('message').notNull() }); +export const VideoLease = pgTable('video_lease', { + id: serial('id').primaryKey(), + created: timestamp('created', { withTimezone: true, mode: 'string' }).notNull().default(sql`Now()`), + updated: timestamp('updated', { withTimezone: true, mode: 'string' }).notNull().default(sql`Now()`), + username: text('username').notNull().references(() => Profile.username), + expiration: timestamp('expiration', { withTimezone: true, mode: 'string' }).notNull().default(sql`Now() + INTERVAL 1 HOUR;`), + path: text('path').notNull() +}); + export const ProfileFeature = pgTable('profile_features', { id: text('id').primaryKey(), path: text('path').notNull().default('/'), From 77ce492b9c5ef4576fabfe8f87585338513240ae Mon Sep 17 00:00:00 2001 From: ingalls Date: Wed, 26 Jun 2024 13:18:09 -0600 Subject: [PATCH 02/19] DB Migration --- api/migrations/0048_illegal_betty_ross.sql | 35 + api/migrations/meta/0048_snapshot.json | 1815 ++++++++++++++++++++ api/migrations/meta/_journal.json | 9 +- 3 files changed, 1858 insertions(+), 1 deletion(-) create mode 100644 api/migrations/0048_illegal_betty_ross.sql create mode 100644 api/migrations/meta/0048_snapshot.json diff --git a/api/migrations/0048_illegal_betty_ross.sql b/api/migrations/0048_illegal_betty_ross.sql new file mode 100644 index 000000000..0dafb3ad6 --- /dev/null +++ b/api/migrations/0048_illegal_betty_ross.sql @@ -0,0 +1,35 @@ +CREATE TABLE IF NOT EXISTS "video_lease" ( + "id" serial PRIMARY KEY NOT NULL, + "created" timestamp with time zone DEFAULT Now() NOT NULL, + "updated" timestamp with time zone DEFAULT Now() NOT NULL, + "username" text NOT NULL, + "expiration" timestamp with time zone DEFAULT Now() + INTERVAL 1 HOUR; NOT NULL, + "path" text NOT NULL +); +--> statement-breakpoint +/* + Unfortunately in current drizzle-kit version we can't automatically get name for primary key. + We are working on making it available! + + Meanwhile you can: + 1. Check pk name in your database, by running + SELECT constraint_name FROM information_schema.table_constraints + WHERE table_schema = 'public' + AND table_name = 'tasks' + AND constraint_type = 'PRIMARY KEY'; + 2. Uncomment code below and paste pk name manually + + Hope to release this update as soon as possible +*/ + +-- ALTER TABLE "tasks" DROP CONSTRAINT "";--> statement-breakpoint +ALTER TABLE "tasks" ADD COLUMN "id" serial NOT NULL;--> statement-breakpoint +ALTER TABLE "tasks" ADD COLUMN "created" timestamp with time zone DEFAULT Now() NOT NULL;--> statement-breakpoint +ALTER TABLE "tasks" ADD COLUMN "updated" timestamp with time zone DEFAULT Now() NOT NULL;--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "video_lease" ADD CONSTRAINT "video_lease_username_profile_username_fk" FOREIGN KEY ("username") REFERENCES "public"."profile"("username") ON DELETE no action ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +ALTER TABLE "tasks" ADD CONSTRAINT "tasks_prefix_unique" UNIQUE("prefix"); \ No newline at end of file diff --git a/api/migrations/meta/0048_snapshot.json b/api/migrations/meta/0048_snapshot.json new file mode 100644 index 000000000..ed8edbc79 --- /dev/null +++ b/api/migrations/meta/0048_snapshot.json @@ -0,0 +1,1815 @@ +{ + "id": "d810730f-35cb-4006-a4c5-570bd683a9f6", + "prevId": "2405ff86-c024-4336-a83e-77548136e510", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.basemaps": { + "name": "basemaps", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bounds": { + "name": "bounds", + "type": "GEOMETRY(POLYGON, 4326)", + "primaryKey": false, + "notNull": false + }, + "center": { + "name": "center", + "type": "GEOMETRY(POINT, 4326)", + "primaryKey": false, + "notNull": false + }, + "minzoom": { + "name": "minzoom", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "maxzoom": { + "name": "maxzoom", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 16 + }, + "format": { + "name": "format", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'png'" + }, + "style": { + "name": "style", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'zxy'" + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'raster'" + } + }, + "indexes": { + "basemaps_username_idx": { + "name": "basemaps_username_idx", + "columns": [ + { + "expression": "username", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "basemaps_username_profile_username_fk": { + "name": "basemaps_username_profile_username_fk", + "tableFrom": "basemaps", + "tableTo": "profile", + "columnsFrom": [ + "username" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.connections": { + "name": "connections", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "agency": { + "name": "agency", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "auth": { + "name": "auth", + "type": "json", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.connection_sinks": { + "name": "connection_sinks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "connection": { + "name": "connection", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + }, + "logging": { + "name": "logging", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "connection_sinks_connection_connections_id_fk": { + "name": "connection_sinks_connection_connections_id_fk", + "tableFrom": "connection_sinks", + "tableTo": "connections", + "columnsFrom": [ + "connection" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.connection_tokens": { + "name": "connection_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "connection": { + "name": "connection", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + } + }, + "indexes": {}, + "foreignKeys": { + "connection_tokens_connection_connections_id_fk": { + "name": "connection_tokens_connection_connections_id_fk", + "tableFrom": "connection_tokens", + "tableTo": "connections", + "columnsFrom": [ + "connection" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.data": { + "name": "data", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "auto_transform": { + "name": "auto_transform", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "mission_sync": { + "name": "mission_sync", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "mission_diff": { + "name": "mission_diff", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "mission_role": { + "name": "mission_role", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'MISSION_SUBSCRIBER'" + }, + "mission_token": { + "name": "mission_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mission_groups": { + "name": "mission_groups", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": [] + }, + "assets": { + "name": "assets", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'[\"*\"]'::json" + }, + "connection": { + "name": "connection", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "data_connection_connections_id_fk": { + "name": "data_connection_connections_id_fk", + "tableFrom": "data", + "tableTo": "connections", + "columnsFrom": [ + "connection" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.icons": { + "name": "icons", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "iconset": { + "name": "iconset", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type2525b": { + "name": "type2525b", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "icons_iconset_iconsets_uid_fk": { + "name": "icons_iconset_iconsets_uid_fk", + "tableFrom": "icons", + "tableTo": "iconsets", + "columnsFrom": [ + "iconset" + ], + "columnsTo": [ + "uid" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.iconsets": { + "name": "iconsets", + "schema": "", + "columns": { + "uid": { + "name": "uid", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_group": { + "name": "default_group", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_friendly": { + "name": "default_friendly", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_hostile": { + "name": "default_hostile", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_neutral": { + "name": "default_neutral", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_unknown": { + "name": "default_unknown", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "skip_resize": { + "name": "skip_resize", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "iconsets_username_idx": { + "name": "iconsets_username_idx", + "columns": [ + { + "expression": "username", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "iconsets_username_profile_username_fk": { + "name": "iconsets_username_profile_username_fk", + "tableFrom": "iconsets", + "tableTo": "profile", + "columnsFrom": [ + "username" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.imports": { + "name": "imports", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Pending'" + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "result": { + "name": "result", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Unknown'" + }, + "mode_id": { + "name": "mode_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "config": { + "name": "config", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + } + }, + "indexes": {}, + "foreignKeys": { + "imports_username_profile_username_fk": { + "name": "imports_username_profile_username_fk", + "tableFrom": "imports", + "tableTo": "profile", + "columnsFrom": [ + "username" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.layers": { + "name": "layers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "priority": { + "name": "priority", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'off'" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "enabled_styles": { + "name": "enabled_styles", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "styles": { + "name": "styles", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + }, + "logging": { + "name": "logging", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "stale": { + "name": "stale", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 20 + }, + "task": { + "name": "task", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "connection": { + "name": "connection", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "cron": { + "name": "cron", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment": { + "name": "environment", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + }, + "config": { + "name": "config", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + }, + "memory": { + "name": "memory", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 128 + }, + "timeout": { + "name": "timeout", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 128 + }, + "data": { + "name": "data", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "schema": { + "name": "schema", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{\"type\":\"object\",\"required\":[],\"properties\":{}}'::json" + } + }, + "indexes": {}, + "foreignKeys": { + "layers_connection_connections_id_fk": { + "name": "layers_connection_connections_id_fk", + "tableFrom": "layers", + "tableTo": "connections", + "columnsFrom": [ + "connection" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "layers_data_data_id_fk": { + "name": "layers_data_data_id_fk", + "tableFrom": "layers", + "tableTo": "data", + "columnsFrom": [ + "data" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "layers_connection_name_unique": { + "name": "layers_connection_name_unique", + "nullsNotDistinct": false, + "columns": [ + "connection", + "name" + ] + } + } + }, + "public.layer_alerts": { + "name": "layer_alerts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "layer": { + "name": "layer", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'alert-circle'" + }, + "priority": { + "name": "priority", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'yellow'" + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Details Unknown'" + }, + "hidden": { + "name": "hidden", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "layer_alerts_layer_layers_id_fk": { + "name": "layer_alerts_layer_layers_id_fk", + "tableFrom": "layer_alerts", + "tableTo": "layers", + "columnsFrom": [ + "layer" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.overlays": { + "name": "overlays", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'vector'" + }, + "styles": { + "name": "styles", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.profile": { + "name": "profile", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'Unknown'" + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "last_login": { + "name": "last_login", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "auth": { + "name": "auth", + "type": "json", + "primaryKey": false, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "phone": { + "name": "phone", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "tak_callsign": { + "name": "tak_callsign", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'CloudTAK User'" + }, + "tak_group": { + "name": "tak_group", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Orange'" + }, + "tak_role": { + "name": "tak_role", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Team Member'" + }, + "tak_loc": { + "name": "tak_loc", + "type": "GEOMETRY(POINT, 4326)", + "primaryKey": false, + "notNull": false + }, + "display_stale": { + "name": "display_stale", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'10 Minutes'" + }, + "display_distance": { + "name": "display_distance", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'mile'" + }, + "display_elevation": { + "name": "display_elevation", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'feet'" + }, + "display_speed": { + "name": "display_speed", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'mi/h'" + }, + "system_admin": { + "name": "system_admin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "agency_admin": { + "name": "agency_admin", + "type": "json", + "primaryKey": false, + "notNull": false, + "default": "'[]'::json" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.profile_chats": { + "name": "profile_chats", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "chatroom": { + "name": "chatroom", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sender_callsign": { + "name": "sender_callsign", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sender_uid": { + "name": "sender_uid", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "profile_chats_username_profile_username_fk": { + "name": "profile_chats_username_profile_username_fk", + "tableFrom": "profile_chats", + "tableTo": "profile", + "columnsFrom": [ + "username" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.profile_features": { + "name": "profile_features", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'/'" + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "properties": { + "name": "properties", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + }, + "geometry": { + "name": "geometry", + "type": "GEOMETRY(GEOMETRYZ, 4326)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "profile_features_username_profile_username_fk": { + "name": "profile_features_username_profile_username_fk", + "tableFrom": "profile_features", + "tableTo": "profile", + "columnsFrom": [ + "username" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.profile_missions": { + "name": "profile_missions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "guid": { + "name": "guid", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.profile_overlays": { + "name": "profile_overlays", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "pos": { + "name": "pos", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 5 + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'vector'" + }, + "opacity": { + "name": "opacity", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "visible": { + "name": "visible", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "styles": { + "name": "styles", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mode_id": { + "name": "mode_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "profile_overlays_username_profile_username_fk": { + "name": "profile_overlays_username_profile_username_fk", + "tableFrom": "profile_overlays", + "tableTo": "profile", + "columnsFrom": [ + "username" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "profile_overlays_username_url_unique": { + "name": "profile_overlays_username_url_unique", + "nullsNotDistinct": false, + "columns": [ + "username", + "url" + ] + } + } + }, + "public.server": { + "name": "server", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Default'" + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "auth": { + "name": "auth", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + }, + "api": { + "name": "api", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider_url": { + "name": "provider_url", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider_secret": { + "name": "provider_secret", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider_client": { + "name": "provider_client", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.settings": { + "name": "settings", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.spatial_ref_sys": { + "name": "spatial_ref_sys", + "schema": "", + "columns": { + "srid": { + "name": "srid", + "type": "integer", + "primaryKey": true, + "notNull": true + }, + "auth_name": { + "name": "auth_name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "auth_srid": { + "name": "auth_srid", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "srtext": { + "name": "srtext", + "type": "varchar(2048)", + "primaryKey": false, + "notNull": false + }, + "proj4text": { + "name": "proj4text", + "type": "varchar(2048)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.tasks": { + "name": "tasks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "repo": { + "name": "repo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "readme": { + "name": "readme", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "tasks_prefix_unique": { + "name": "tasks_prefix_unique", + "nullsNotDistinct": false, + "columns": [ + "prefix" + ] + } + } + }, + "public.tokens": { + "name": "tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.video_lease": { + "name": "video_lease", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expiration": { + "name": "expiration", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now() + INTERVAL 1 HOUR;" + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "video_lease_username_profile_username_fk": { + "name": "video_lease_username_profile_username_fk", + "tableFrom": "video_lease", + "tableTo": "profile", + "columnsFrom": [ + "username" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": {}, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/api/migrations/meta/_journal.json b/api/migrations/meta/_journal.json index 607db42e7..ac97ecb80 100644 --- a/api/migrations/meta/_journal.json +++ b/api/migrations/meta/_journal.json @@ -337,6 +337,13 @@ "when": 1719000234715, "tag": "0047_sticky_morbius", "breakpoints": true + }, + { + "idx": 48, + "version": "7", + "when": 1719429489397, + "tag": "0048_illegal_betty_ross", + "breakpoints": true } ] -} +} \ No newline at end of file From 80780df09e7ddd631fee90cf552a304d15485bb9 Mon Sep 17 00:00:00 2001 From: ingalls Date: Wed, 26 Jun 2024 13:25:22 -0600 Subject: [PATCH 03/19] Add Video Lease DB --- api/lib/models.ts | 3 ++ api/routes/video-lease.ts | 72 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 api/routes/video-lease.ts diff --git a/api/lib/models.ts b/api/lib/models.ts index 13c7a4aa5..7d3efae1e 100644 --- a/api/lib/models.ts +++ b/api/lib/models.ts @@ -27,6 +27,8 @@ export default class Models { ProfileOverlay: Modeler; ProfileMission: Modeler; + VideoLease: Modeler; + Task: Modeler; Iconset: Modeler; @@ -49,6 +51,7 @@ export default class Models { this.ProfileMission = new Modeler(pg, pgtypes.ProfileMission); this.Basemap = new Modeler(pg, pgtypes.Basemap); this.Import = new Modeler(pg, pgtypes.Import); + this.VideoLease = new Modeler(pg, pgtypes.VideoLease); this.Connection = new Modeler(pg, pgtypes.Connection); this.ConnectionToken = new Modeler(pg, pgtypes.ConnectionToken); this.ConnectionSink = new Modeler(pg, pgtypes.ConnectionSink); diff --git a/api/routes/video-lease.ts b/api/routes/video-lease.ts new file mode 100644 index 000000000..b1df852f4 --- /dev/null +++ b/api/routes/video-lease.ts @@ -0,0 +1,72 @@ +import { Type } from '@sinclair/typebox' +import Schema from '@openaddresses/batch-schema'; +import Err from '@openaddresses/batch-error'; +import Auth from '../lib/auth.js'; +import Config from '../lib/config.js'; +import jwt from 'jsonwebtoken'; +import { sql } from 'drizzle-orm'; +import { Token } from '../lib/schema.js'; +import { StandardResponse, CreateProfileTokenResponse, ProfileTokenResponse } from '../lib/types.js'; +import * as Default from '../lib/limits.js'; + +export default async function router(schema: Schema, config: Config) { + await schema.get('/video/lease', { + name: 'List Leases', + group: 'VideoLease', + description: 'List all vide', + query: Type.Object({ + limit: Default.Limit, + page: Default.Page, + order: Default.Order, + sort: Type.Optional(Type.String({default: 'created', enum: Object.keys(Token) })), + filter: Default.Filter + }), + res: Type.Object({ + total: Type.Integer(), + items: Type.Array(ProfileTokenResponse) + }) + }, async (req, res) => { + try { + const user = await Auth.as_user(config, req); + + const list = await config.models.Token.list({ + limit: req.query.limit, + page: req.query.page, + order: req.query.order, + sort: req.query.sort, + where: sql` + name ~* ${req.query.filter} + AND username = ${user.email} + ` + }); + + return res.json(list); + } catch (err) { + return Err.respond(err, res); + } + }); + + await schema.post('/video/lease', { + name: 'Create Lease', + group: 'VideoLease', + description: 'Create a new video Lease', + body: Type.Object({ + name: Type.String() + }), + res: CreateProfileTokenResponse, + }, async (req, res) => { + try { + const user = await Auth.as_user(config, req); + + const token = await config.models.Token.generate({ + ...req.body, + token: 'etl.' + jwt.sign({ id: user.email, access: 'profile' }, config.SigningSecret), + email: user.email + }); + + return res.json(token); + } catch (err) { + return Err.respond(err, res); + } + }); +} From 36c360c785a04554e2c2019f45eb8c1a764b2ae5 Mon Sep 17 00:00:00 2001 From: ingalls Date: Wed, 26 Jun 2024 13:32:26 -0600 Subject: [PATCH 04/19] Add Name --- api/lib/schema.ts | 1 + api/migrations/0048_illegal_betty_ross.sql | 8 ++------ api/routes/video-lease.ts | 2 +- api/web/src/components/Profile.vue | 10 ++++++++++ api/web/src/main.js | 4 ++++ 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/api/lib/schema.ts b/api/lib/schema.ts index 46db34418..6ea4185d6 100644 --- a/api/lib/schema.ts +++ b/api/lib/schema.ts @@ -53,6 +53,7 @@ export const ProfileChat = pgTable('profile_chats', { export const VideoLease = pgTable('video_lease', { id: serial('id').primaryKey(), + name: text('name').notNull(), created: timestamp('created', { withTimezone: true, mode: 'string' }).notNull().default(sql`Now()`), updated: timestamp('updated', { withTimezone: true, mode: 'string' }).notNull().default(sql`Now()`), username: text('username').notNull().references(() => Profile.username), diff --git a/api/migrations/0048_illegal_betty_ross.sql b/api/migrations/0048_illegal_betty_ross.sql index 0dafb3ad6..a4455024c 100644 --- a/api/migrations/0048_illegal_betty_ross.sql +++ b/api/migrations/0048_illegal_betty_ross.sql @@ -3,7 +3,7 @@ CREATE TABLE IF NOT EXISTS "video_lease" ( "created" timestamp with time zone DEFAULT Now() NOT NULL, "updated" timestamp with time zone DEFAULT Now() NOT NULL, "username" text NOT NULL, - "expiration" timestamp with time zone DEFAULT Now() + INTERVAL 1 HOUR; NOT NULL, + "expiration" timestamp with time zone DEFAULT Now() + INTERVAL '1 HOUR' NOT NULL, "path" text NOT NULL ); --> statement-breakpoint @@ -22,14 +22,10 @@ CREATE TABLE IF NOT EXISTS "video_lease" ( Hope to release this update as soon as possible */ --- ALTER TABLE "tasks" DROP CONSTRAINT "";--> statement-breakpoint -ALTER TABLE "tasks" ADD COLUMN "id" serial NOT NULL;--> statement-breakpoint -ALTER TABLE "tasks" ADD COLUMN "created" timestamp with time zone DEFAULT Now() NOT NULL;--> statement-breakpoint -ALTER TABLE "tasks" ADD COLUMN "updated" timestamp with time zone DEFAULT Now() NOT NULL;--> statement-breakpoint DO $$ BEGIN ALTER TABLE "video_lease" ADD CONSTRAINT "video_lease_username_profile_username_fk" FOREIGN KEY ("username") REFERENCES "public"."profile"("username") ON DELETE no action ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint -ALTER TABLE "tasks" ADD CONSTRAINT "tasks_prefix_unique" UNIQUE("prefix"); \ No newline at end of file +ALTER TABLE "tasks" ADD CONSTRAINT "tasks_prefix_unique" UNIQUE("prefix"); diff --git a/api/routes/video-lease.ts b/api/routes/video-lease.ts index b1df852f4..3f41bd7cd 100644 --- a/api/routes/video-lease.ts +++ b/api/routes/video-lease.ts @@ -29,7 +29,7 @@ export default async function router(schema: Schema, config: Config) { try { const user = await Auth.as_user(config, req); - const list = await config.models.Token.list({ + const list = await config.models.VideoLease.list({ limit: req.query.limit, page: req.query.page, order: req.query.order, diff --git a/api/web/src/components/Profile.vue b/api/web/src/components/Profile.vue index 71924ea4a..ac827656c 100644 --- a/api/web/src/components/Profile.vue +++ b/api/web/src/components/Profile.vue @@ -47,6 +47,14 @@ }' @click='$router.push(`/profile/files`)' >Files + Video Leases import('./components/Profile/ProfileTokens.vue') + },{ + path: 'videos', + name: 'profile-videos', + component: () => import('./components/Profile/ProfileVideos.vue') }] }, From 0c4d4b519f3ff0ef04ce9211b28004359558e856 Mon Sep 17 00:00:00 2001 From: ingalls Date: Wed, 26 Jun 2024 13:46:05 -0600 Subject: [PATCH 05/19] Add Video Lease API --- api/lib/types.ts | 4 + api/routes/video-lease.ts | 52 ++++++-- .../src/components/Profile/ProfileVideos.vue | 111 ++++++++++++++++++ 3 files changed, 158 insertions(+), 9 deletions(-) create mode 100644 api/web/src/components/Profile/ProfileVideos.vue diff --git a/api/lib/types.ts b/api/lib/types.ts index 6b5c73258..bd6df1ca9 100644 --- a/api/lib/types.ts +++ b/api/lib/types.ts @@ -58,6 +58,10 @@ export const ProfileResponse = Type.Object({ display_speed: Type.String() }); +export const VideoLeaseResponse = createSelectSchema(schemas.VideoLease, { + id: Type.Integer(), +}); + export const OverlayResponse = createSelectSchema(schemas.Overlay, { id: Type.Integer(), }); diff --git a/api/routes/video-lease.ts b/api/routes/video-lease.ts index 3f41bd7cd..406eade54 100644 --- a/api/routes/video-lease.ts +++ b/api/routes/video-lease.ts @@ -1,12 +1,12 @@ import { Type } from '@sinclair/typebox' import Schema from '@openaddresses/batch-schema'; import Err from '@openaddresses/batch-error'; -import Auth from '../lib/auth.js'; +import Auth, { AuthUserAccess } from '../lib/auth.js'; import Config from '../lib/config.js'; import jwt from 'jsonwebtoken'; import { sql } from 'drizzle-orm'; import { Token } from '../lib/schema.js'; -import { StandardResponse, CreateProfileTokenResponse, ProfileTokenResponse } from '../lib/types.js'; +import { StandardResponse, VideoLeaseResponse } from '../lib/types.js'; import * as Default from '../lib/limits.js'; export default async function router(schema: Schema, config: Config) { @@ -51,20 +51,54 @@ export default async function router(schema: Schema, config: Config) { group: 'VideoLease', description: 'Create a new video Lease', body: Type.Object({ - name: Type.String() + name: Type.String(), + duration: Type.Integer() }), - res: CreateProfileTokenResponse, + res: VideoLeaseResponse, }, async (req, res) => { try { const user = await Auth.as_user(config, req); - const token = await config.models.Token.generate({ + if (user.access !== AuthUserAccess.ADMIN &&req.body.duration > 60 * 60 * 16) { + throw new Err(400, null, 'Only Administrators can request a lease > 16 hours') + } + + const lease = await config.models.VideoLease.generate({ ...req.body, - token: 'etl.' + jwt.sign({ id: user.email, access: 'profile' }, config.SigningSecret), - email: user.email - }); + username: user.email + }) + + return res.json(lease); + } catch (err) { + return Err.respond(err, res); + } + }); - return res.json(token); + await schema.delete('/video/lease/:lease', { + name: 'Delete Lease', + group: 'VideoLease', + description: 'Delete a video Lease', + params: Type.Object({ + lease: Type.String() + }), + res: StandardResponse + }, async (req, res) => { + try { + const user = await Auth.as_user(config, req); + + if (user.access === AuthUserAccess.ADMIN) { + await config.models.VideoLease.delete(req.params.lease); + } else { + await config.models.VideoLease.delete(sql` + username = ${user.email} + AND id = ${req.params.lease} + `); + } + + return res.json({ + status: 200, + message: 'Video Lease Deleted' + }); } catch (err) { return Err.respond(err, res); } diff --git a/api/web/src/components/Profile/ProfileVideos.vue b/api/web/src/components/Profile/ProfileVideos.vue new file mode 100644 index 000000000..c1d9a543f --- /dev/null +++ b/api/web/src/components/Profile/ProfileVideos.vue @@ -0,0 +1,111 @@ + + + From 8a4280ac71176ffce5d7970e16ef1a0438b0cdb3 Mon Sep 17 00:00:00 2001 From: ingalls Date: Wed, 26 Jun 2024 13:55:19 -0600 Subject: [PATCH 06/19] Create Lease --- api/routes/video-lease.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/routes/video-lease.ts b/api/routes/video-lease.ts index 406eade54..10be702e7 100644 --- a/api/routes/video-lease.ts +++ b/api/routes/video-lease.ts @@ -6,6 +6,7 @@ import Config from '../lib/config.js'; import jwt from 'jsonwebtoken'; import { sql } from 'drizzle-orm'; import { Token } from '../lib/schema.js'; +import { randomUUID } from 'node:crypto'; import { StandardResponse, VideoLeaseResponse } from '../lib/types.js'; import * as Default from '../lib/limits.js'; @@ -23,7 +24,7 @@ export default async function router(schema: Schema, config: Config) { }), res: Type.Object({ total: Type.Integer(), - items: Type.Array(ProfileTokenResponse) + items: Type.Array(VideoLeaseResponse) }) }, async (req, res) => { try { @@ -65,6 +66,7 @@ export default async function router(schema: Schema, config: Config) { const lease = await config.models.VideoLease.generate({ ...req.body, + path: randomUUID(), username: user.email }) From 0bbab888b265e42a2ee26b5dd6e9a1cba32eca2e Mon Sep 17 00:00:00 2001 From: ingalls Date: Wed, 26 Jun 2024 13:56:29 -0600 Subject: [PATCH 07/19] Remove Video Lease --- api/routes/video-lease.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/api/routes/video-lease.ts b/api/routes/video-lease.ts index 10be702e7..525bd4b91 100644 --- a/api/routes/video-lease.ts +++ b/api/routes/video-lease.ts @@ -3,7 +3,6 @@ import Schema from '@openaddresses/batch-schema'; import Err from '@openaddresses/batch-error'; import Auth, { AuthUserAccess } from '../lib/auth.js'; import Config from '../lib/config.js'; -import jwt from 'jsonwebtoken'; import { sql } from 'drizzle-orm'; import { Token } from '../lib/schema.js'; import { randomUUID } from 'node:crypto'; From 9e4c2ee15014e2021b415029d43f0e7ff9eb63d1 Mon Sep 17 00:00:00 2001 From: ingalls Date: Wed, 26 Jun 2024 13:56:42 -0600 Subject: [PATCH 08/19] DB Migration --- api/migrations/0049_silly_blink.sql | 1 + api/migrations/meta/0049_snapshot.json | 1821 ++++++++++++++++++++++++ api/migrations/meta/_journal.json | 7 + 3 files changed, 1829 insertions(+) create mode 100644 api/migrations/0049_silly_blink.sql create mode 100644 api/migrations/meta/0049_snapshot.json diff --git a/api/migrations/0049_silly_blink.sql b/api/migrations/0049_silly_blink.sql new file mode 100644 index 000000000..23510a185 --- /dev/null +++ b/api/migrations/0049_silly_blink.sql @@ -0,0 +1 @@ +ALTER TABLE "video_lease" ADD COLUMN "name" text NOT NULL; \ No newline at end of file diff --git a/api/migrations/meta/0049_snapshot.json b/api/migrations/meta/0049_snapshot.json new file mode 100644 index 000000000..4720a65a8 --- /dev/null +++ b/api/migrations/meta/0049_snapshot.json @@ -0,0 +1,1821 @@ +{ + "id": "06bbded0-b95d-4531-b6aa-dddaf5394f70", + "prevId": "d810730f-35cb-4006-a4c5-570bd683a9f6", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.basemaps": { + "name": "basemaps", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bounds": { + "name": "bounds", + "type": "GEOMETRY(POLYGON, 4326)", + "primaryKey": false, + "notNull": false + }, + "center": { + "name": "center", + "type": "GEOMETRY(POINT, 4326)", + "primaryKey": false, + "notNull": false + }, + "minzoom": { + "name": "minzoom", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "maxzoom": { + "name": "maxzoom", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 16 + }, + "format": { + "name": "format", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'png'" + }, + "style": { + "name": "style", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'zxy'" + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'raster'" + } + }, + "indexes": { + "basemaps_username_idx": { + "name": "basemaps_username_idx", + "columns": [ + { + "expression": "username", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "basemaps_username_profile_username_fk": { + "name": "basemaps_username_profile_username_fk", + "tableFrom": "basemaps", + "tableTo": "profile", + "columnsFrom": [ + "username" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.connections": { + "name": "connections", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "agency": { + "name": "agency", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "auth": { + "name": "auth", + "type": "json", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.connection_sinks": { + "name": "connection_sinks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "connection": { + "name": "connection", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + }, + "logging": { + "name": "logging", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "connection_sinks_connection_connections_id_fk": { + "name": "connection_sinks_connection_connections_id_fk", + "tableFrom": "connection_sinks", + "tableTo": "connections", + "columnsFrom": [ + "connection" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.connection_tokens": { + "name": "connection_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "connection": { + "name": "connection", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + } + }, + "indexes": {}, + "foreignKeys": { + "connection_tokens_connection_connections_id_fk": { + "name": "connection_tokens_connection_connections_id_fk", + "tableFrom": "connection_tokens", + "tableTo": "connections", + "columnsFrom": [ + "connection" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.data": { + "name": "data", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "auto_transform": { + "name": "auto_transform", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "mission_sync": { + "name": "mission_sync", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "mission_diff": { + "name": "mission_diff", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "mission_role": { + "name": "mission_role", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'MISSION_SUBSCRIBER'" + }, + "mission_token": { + "name": "mission_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mission_groups": { + "name": "mission_groups", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": [] + }, + "assets": { + "name": "assets", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'[\"*\"]'::json" + }, + "connection": { + "name": "connection", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "data_connection_connections_id_fk": { + "name": "data_connection_connections_id_fk", + "tableFrom": "data", + "tableTo": "connections", + "columnsFrom": [ + "connection" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.icons": { + "name": "icons", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "iconset": { + "name": "iconset", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type2525b": { + "name": "type2525b", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "icons_iconset_iconsets_uid_fk": { + "name": "icons_iconset_iconsets_uid_fk", + "tableFrom": "icons", + "tableTo": "iconsets", + "columnsFrom": [ + "iconset" + ], + "columnsTo": [ + "uid" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.iconsets": { + "name": "iconsets", + "schema": "", + "columns": { + "uid": { + "name": "uid", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_group": { + "name": "default_group", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_friendly": { + "name": "default_friendly", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_hostile": { + "name": "default_hostile", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_neutral": { + "name": "default_neutral", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_unknown": { + "name": "default_unknown", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "skip_resize": { + "name": "skip_resize", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "iconsets_username_idx": { + "name": "iconsets_username_idx", + "columns": [ + { + "expression": "username", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "iconsets_username_profile_username_fk": { + "name": "iconsets_username_profile_username_fk", + "tableFrom": "iconsets", + "tableTo": "profile", + "columnsFrom": [ + "username" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.imports": { + "name": "imports", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Pending'" + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "result": { + "name": "result", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Unknown'" + }, + "mode_id": { + "name": "mode_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "config": { + "name": "config", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + } + }, + "indexes": {}, + "foreignKeys": { + "imports_username_profile_username_fk": { + "name": "imports_username_profile_username_fk", + "tableFrom": "imports", + "tableTo": "profile", + "columnsFrom": [ + "username" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.layers": { + "name": "layers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "priority": { + "name": "priority", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'off'" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "enabled_styles": { + "name": "enabled_styles", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "styles": { + "name": "styles", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + }, + "logging": { + "name": "logging", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "stale": { + "name": "stale", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 20 + }, + "task": { + "name": "task", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "connection": { + "name": "connection", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "cron": { + "name": "cron", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment": { + "name": "environment", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + }, + "config": { + "name": "config", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + }, + "memory": { + "name": "memory", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 128 + }, + "timeout": { + "name": "timeout", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 128 + }, + "data": { + "name": "data", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "schema": { + "name": "schema", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{\"type\":\"object\",\"required\":[],\"properties\":{}}'::json" + } + }, + "indexes": {}, + "foreignKeys": { + "layers_connection_connections_id_fk": { + "name": "layers_connection_connections_id_fk", + "tableFrom": "layers", + "tableTo": "connections", + "columnsFrom": [ + "connection" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "layers_data_data_id_fk": { + "name": "layers_data_data_id_fk", + "tableFrom": "layers", + "tableTo": "data", + "columnsFrom": [ + "data" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "layers_connection_name_unique": { + "name": "layers_connection_name_unique", + "nullsNotDistinct": false, + "columns": [ + "connection", + "name" + ] + } + } + }, + "public.layer_alerts": { + "name": "layer_alerts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "layer": { + "name": "layer", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'alert-circle'" + }, + "priority": { + "name": "priority", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'yellow'" + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Details Unknown'" + }, + "hidden": { + "name": "hidden", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "layer_alerts_layer_layers_id_fk": { + "name": "layer_alerts_layer_layers_id_fk", + "tableFrom": "layer_alerts", + "tableTo": "layers", + "columnsFrom": [ + "layer" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.overlays": { + "name": "overlays", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'vector'" + }, + "styles": { + "name": "styles", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.profile": { + "name": "profile", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'Unknown'" + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "last_login": { + "name": "last_login", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "auth": { + "name": "auth", + "type": "json", + "primaryKey": false, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "phone": { + "name": "phone", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "tak_callsign": { + "name": "tak_callsign", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'CloudTAK User'" + }, + "tak_group": { + "name": "tak_group", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Orange'" + }, + "tak_role": { + "name": "tak_role", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Team Member'" + }, + "tak_loc": { + "name": "tak_loc", + "type": "GEOMETRY(POINT, 4326)", + "primaryKey": false, + "notNull": false + }, + "display_stale": { + "name": "display_stale", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'10 Minutes'" + }, + "display_distance": { + "name": "display_distance", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'mile'" + }, + "display_elevation": { + "name": "display_elevation", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'feet'" + }, + "display_speed": { + "name": "display_speed", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'mi/h'" + }, + "system_admin": { + "name": "system_admin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "agency_admin": { + "name": "agency_admin", + "type": "json", + "primaryKey": false, + "notNull": false, + "default": "'[]'::json" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.profile_chats": { + "name": "profile_chats", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "chatroom": { + "name": "chatroom", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sender_callsign": { + "name": "sender_callsign", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sender_uid": { + "name": "sender_uid", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "profile_chats_username_profile_username_fk": { + "name": "profile_chats_username_profile_username_fk", + "tableFrom": "profile_chats", + "tableTo": "profile", + "columnsFrom": [ + "username" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.profile_features": { + "name": "profile_features", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'/'" + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "properties": { + "name": "properties", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + }, + "geometry": { + "name": "geometry", + "type": "GEOMETRY(GEOMETRYZ, 4326)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "profile_features_username_profile_username_fk": { + "name": "profile_features_username_profile_username_fk", + "tableFrom": "profile_features", + "tableTo": "profile", + "columnsFrom": [ + "username" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.profile_missions": { + "name": "profile_missions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "guid": { + "name": "guid", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.profile_overlays": { + "name": "profile_overlays", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "pos": { + "name": "pos", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 5 + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'vector'" + }, + "opacity": { + "name": "opacity", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "visible": { + "name": "visible", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "styles": { + "name": "styles", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mode_id": { + "name": "mode_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "profile_overlays_username_profile_username_fk": { + "name": "profile_overlays_username_profile_username_fk", + "tableFrom": "profile_overlays", + "tableTo": "profile", + "columnsFrom": [ + "username" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "profile_overlays_username_url_unique": { + "name": "profile_overlays_username_url_unique", + "nullsNotDistinct": false, + "columns": [ + "username", + "url" + ] + } + } + }, + "public.server": { + "name": "server", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Default'" + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "auth": { + "name": "auth", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'::json" + }, + "api": { + "name": "api", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider_url": { + "name": "provider_url", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider_secret": { + "name": "provider_secret", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider_client": { + "name": "provider_client", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.settings": { + "name": "settings", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.spatial_ref_sys": { + "name": "spatial_ref_sys", + "schema": "", + "columns": { + "srid": { + "name": "srid", + "type": "integer", + "primaryKey": true, + "notNull": true + }, + "auth_name": { + "name": "auth_name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "auth_srid": { + "name": "auth_srid", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "srtext": { + "name": "srtext", + "type": "varchar(2048)", + "primaryKey": false, + "notNull": false + }, + "proj4text": { + "name": "proj4text", + "type": "varchar(2048)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.tasks": { + "name": "tasks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "repo": { + "name": "repo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "readme": { + "name": "readme", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "tasks_prefix_unique": { + "name": "tasks_prefix_unique", + "nullsNotDistinct": false, + "columns": [ + "prefix" + ] + } + } + }, + "public.tokens": { + "name": "tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.video_lease": { + "name": "video_lease", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created": { + "name": "created", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "updated": { + "name": "updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now()" + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expiration": { + "name": "expiration", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "Now() + INTERVAL 1 HOUR;" + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "video_lease_username_profile_username_fk": { + "name": "video_lease_username_profile_username_fk", + "tableFrom": "video_lease", + "tableTo": "profile", + "columnsFrom": [ + "username" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": {}, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/api/migrations/meta/_journal.json b/api/migrations/meta/_journal.json index ac97ecb80..2a1a2bde6 100644 --- a/api/migrations/meta/_journal.json +++ b/api/migrations/meta/_journal.json @@ -344,6 +344,13 @@ "when": 1719429489397, "tag": "0048_illegal_betty_ross", "breakpoints": true + }, + { + "idx": 49, + "version": "7", + "when": 1719431802482, + "tag": "0049_silly_blink", + "breakpoints": true } ] } \ No newline at end of file From 66ceda07f4e3e253a3ae3c598a979c39202aed79 Mon Sep 17 00:00:00 2001 From: ingalls Date: Wed, 26 Jun 2024 14:15:59 -0600 Subject: [PATCH 09/19] Update IconChevron Right --- api/package-lock.json | 24 ++++++------ .../src/components/CloudTAK/Menu/Overlays.vue | 39 +++++++++++++------ 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/api/package-lock.json b/api/package-lock.json index 01295ad44..3c43de15e 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -557,9 +557,9 @@ } }, "node_modules/@aws-sdk/client-ec2": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-ec2/-/client-ec2-3.600.0.tgz", - "integrity": "sha512-Rh2BqT7nmuP5ysLe0KFNofils/ZU1nH66XdGEk9WwIHaccCtt/7xDUIwTzrle9B8004O2bGTF2rE4eilvQ4vng==", + "version": "3.604.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ec2/-/client-ec2-3.604.0.tgz", + "integrity": "sha512-ZnmqKRewjYkEps7tRoTaA7yo8wSgwOHqGU+Pw6wVsaR7RqmfxCtWb6QQNAk7sqqv1zv15a8TNfA/oekA5fFUPw==", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -4476,9 +4476,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.14.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.8.tgz", - "integrity": "sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==", + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", "dependencies": { "undici-types": "~5.26.4" } @@ -4857,9 +4857,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -7988,9 +7988,9 @@ } }, "node_modules/glob/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dependencies": { "brace-expansion": "^2.0.1" }, diff --git a/api/web/src/components/CloudTAK/Menu/Overlays.vue b/api/web/src/components/CloudTAK/Menu/Overlays.vue index fc4a5759a..111a0991a 100644 --- a/api/web/src/components/CloudTAK/Menu/Overlays.vue +++ b/api/web/src/components/CloudTAK/Menu/Overlays.vue @@ -14,7 +14,7 @@ @@ -31,14 +31,14 @@ @@ -47,12 +47,12 @@ @@ -69,26 +69,38 @@ + + +
-
+