refactor: drop webhook_token_prefix from native_trigger table

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
HugoCasa
2026-03-13 16:16:12 +01:00
co-authored by Claude Opus 4.5
parent 98077cab34
commit 5cbdcbf557
11 changed files with 47 additions and 72 deletions
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "\n SELECT\n external_id,\n workspace_id,\n service_name AS \"service_name!: ServiceName\",\n script_path,\n is_flow,\n webhook_token_prefix,\n webhook_token_hash,\n service_config,\n error,\n created_at,\n updated_at\n FROM\n native_trigger\n WHERE\n workspace_id = $1\n AND service_name = $2\n AND script_path = $3\n AND is_flow = $4\n LIMIT 1\n ",
"query": "\n SELECT\n external_id,\n workspace_id,\n service_name AS \"service_name!: ServiceName\",\n script_path,\n is_flow,\n webhook_token_hash,\n service_config,\n error,\n created_at,\n updated_at\n FROM\n native_trigger\n WHERE\n workspace_id = $1\n AND service_name = $2\n AND script_path = $3\n AND is_flow = $4\n LIMIT 1\n ",
"describe": {
"columns": [
{
@@ -40,31 +40,26 @@
},
{
"ordinal": 5,
"name": "webhook_token_prefix",
"type_info": "Varchar"
},
{
"ordinal": 6,
"name": "webhook_token_hash",
"type_info": "Varchar"
},
{
"ordinal": 7,
"ordinal": 6,
"name": "service_config",
"type_info": "Jsonb"
},
{
"ordinal": 8,
"ordinal": 7,
"name": "error",
"type_info": "Text"
},
{
"ordinal": 9,
"ordinal": 8,
"name": "created_at",
"type_info": "Timestamptz"
},
{
"ordinal": 10,
"ordinal": 9,
"name": "updated_at",
"type_info": "Timestamptz"
}
@@ -93,7 +88,6 @@
false,
false,
false,
false,
true,
true,
true,
@@ -101,5 +95,5 @@
false
]
},
"hash": "213571171fadd8edd4e38de03f6ae3da5e81be01b8829505da8a2ae6b4266477"
"hash": "1a69ef11a3f361f105c2a8af7b7fa182f3953150ade1756259b31a50e9308fce"
}
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "\n UPDATE native_trigger\n SET script_path = $1, is_flow = $2, webhook_token_prefix = $3, webhook_token_hash = $4, service_config = $5, error = NULL, updated_at = NOW()\n WHERE\n workspace_id = $6\n AND service_name = $7\n AND external_id = $8\n ",
"query": "\n UPDATE native_trigger\n SET script_path = $1, is_flow = $2, webhook_token_hash = $3, service_config = $4, error = NULL, updated_at = NOW()\n WHERE\n workspace_id = $5\n AND service_name = $6\n AND external_id = $7\n ",
"describe": {
"columns": [],
"parameters": {
@@ -8,7 +8,6 @@
"Varchar",
"Bool",
"Varchar",
"Varchar",
"Jsonb",
"Text",
{
@@ -27,5 +26,5 @@
},
"nullable": []
},
"hash": "966772bce6305a850f67291a0fe181504e4796e1d5004a26a870947dbeddc533"
"hash": "40a8bf6a5a42c275d73221bc5f386f2e18cb911352551d0a34bf1933e558674e"
}
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "\n INSERT INTO native_trigger (\n external_id,\n workspace_id,\n service_name,\n script_path,\n is_flow,\n webhook_token_prefix,\n webhook_token_hash,\n service_config\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8\n )\n ON CONFLICT (external_id, workspace_id, service_name)\n DO UPDATE SET script_path = $4, is_flow = $5, webhook_token_prefix = $6, webhook_token_hash = $7, service_config = $8, error = NULL, updated_at = NOW()\n ",
"query": "\n INSERT INTO native_trigger (\n external_id,\n workspace_id,\n service_name,\n script_path,\n is_flow,\n webhook_token_hash,\n service_config\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7\n )\n ON CONFLICT (external_id, workspace_id, service_name)\n DO UPDATE SET script_path = $4, is_flow = $5, webhook_token_hash = $6, service_config = $7, error = NULL, updated_at = NOW()\n ",
"describe": {
"columns": [],
"parameters": {
@@ -21,11 +21,10 @@
"Varchar",
"Bool",
"Varchar",
"Varchar",
"Jsonb"
]
},
"nullable": []
},
"hash": "4a51df985fd0edf8d067a225885cd5af3cae0d0a321744406acb05cd100b1cde"
"hash": "6f9386dfcb4c201525722aee3caa25bf2f3a35d90f7354c7d3aef8a3538a03a7"
}
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "\n UPDATE native_trigger\n SET service_config = $1,\n webhook_token_prefix = COALESCE($5, webhook_token_prefix),\n webhook_token_hash = COALESCE($6, webhook_token_hash),\n updated_at = NOW()\n WHERE\n workspace_id = $2\n AND service_name = $3\n AND external_id = $4\n ",
"query": "\n UPDATE native_trigger\n SET service_config = $1,\n webhook_token_hash = COALESCE($5, webhook_token_hash),\n updated_at = NOW()\n WHERE\n workspace_id = $2\n AND service_name = $3\n AND external_id = $4\n ",
"describe": {
"columns": [],
"parameters": {
@@ -19,11 +19,10 @@
}
},
"Text",
"Varchar",
"Varchar"
]
},
"nullable": []
},
"hash": "3d9f6390a26ccaf03ca43b414e578a2c606c5dadd7dc972c8faf5384f913acaf"
"hash": "95e77019bca83ce43b629e7aac429b09a60d732099a2de9e001d2b40a8e919a9"
}
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "\n SELECT\n nt.external_id,\n nt.workspace_id,\n nt.service_name AS \"service_name!: ServiceName\",\n nt.script_path,\n nt.is_flow,\n nt.webhook_token_prefix,\n nt.webhook_token_hash,\n nt.service_config,\n nt.error,\n nt.created_at,\n nt.updated_at\n FROM\n native_trigger nt\n WHERE\n nt.workspace_id = $1 AND\n nt.service_name = $2 AND\n ($5::text IS NULL OR nt.script_path = $5) AND\n ($6::bool IS NULL OR nt.is_flow = $6) AND\n (\n (nt.is_flow = false AND EXISTS (\n SELECT 1 FROM script s\n WHERE s.workspace_id = nt.workspace_id\n AND s.path = nt.script_path\n ))\n OR\n (nt.is_flow = true AND EXISTS (\n SELECT 1 FROM flow f\n WHERE f.workspace_id = nt.workspace_id\n AND f.path = nt.script_path\n ))\n )\n LIMIT $3\n OFFSET $4\n ",
"query": "\n SELECT\n nt.external_id,\n nt.workspace_id,\n nt.service_name AS \"service_name!: ServiceName\",\n nt.script_path,\n nt.is_flow,\n nt.webhook_token_hash,\n nt.service_config,\n nt.error,\n nt.created_at,\n nt.updated_at\n FROM\n native_trigger nt\n WHERE\n nt.workspace_id = $1 AND\n nt.service_name = $2 AND\n ($5::text IS NULL OR nt.script_path = $5) AND\n ($6::bool IS NULL OR nt.is_flow = $6) AND\n (\n (nt.is_flow = false AND EXISTS (\n SELECT 1 FROM script s\n WHERE s.workspace_id = nt.workspace_id\n AND s.path = nt.script_path\n ))\n OR\n (nt.is_flow = true AND EXISTS (\n SELECT 1 FROM flow f\n WHERE f.workspace_id = nt.workspace_id\n AND f.path = nt.script_path\n ))\n )\n LIMIT $3\n OFFSET $4\n ",
"describe": {
"columns": [
{
@@ -40,31 +40,26 @@
},
{
"ordinal": 5,
"name": "webhook_token_prefix",
"type_info": "Varchar"
},
{
"ordinal": 6,
"name": "webhook_token_hash",
"type_info": "Varchar"
},
{
"ordinal": 7,
"ordinal": 6,
"name": "service_config",
"type_info": "Jsonb"
},
{
"ordinal": 8,
"ordinal": 7,
"name": "error",
"type_info": "Text"
},
{
"ordinal": 9,
"ordinal": 8,
"name": "created_at",
"type_info": "Timestamptz"
},
{
"ordinal": 10,
"ordinal": 9,
"name": "updated_at",
"type_info": "Timestamptz"
}
@@ -95,7 +90,6 @@
false,
false,
false,
false,
true,
true,
true,
@@ -103,5 +97,5 @@
false
]
},
"hash": "b0969b8cd77b4e715a07a4173ef9f8b045d68b0317932c38246b535fd81e5087"
"hash": "a115d8ea786907561afdbbc07d11dc715d80b00c0e79b61b0057a3ae3886a85e"
}
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "\n SELECT\n external_id,\n workspace_id,\n service_name AS \"service_name!: ServiceName\",\n script_path,\n is_flow,\n webhook_token_prefix,\n webhook_token_hash,\n service_config,\n error,\n created_at,\n updated_at\n FROM\n native_trigger\n WHERE\n workspace_id = $1\n AND service_name = $2\n AND external_id = $3\n ",
"query": "\n SELECT\n external_id,\n workspace_id,\n service_name AS \"service_name!: ServiceName\",\n script_path,\n is_flow,\n webhook_token_hash,\n service_config,\n error,\n created_at,\n updated_at\n FROM\n native_trigger\n WHERE\n workspace_id = $1\n AND service_name = $2\n AND external_id = $3\n ",
"describe": {
"columns": [
{
@@ -40,31 +40,26 @@
},
{
"ordinal": 5,
"name": "webhook_token_prefix",
"type_info": "Varchar"
},
{
"ordinal": 6,
"name": "webhook_token_hash",
"type_info": "Varchar"
},
{
"ordinal": 7,
"ordinal": 6,
"name": "service_config",
"type_info": "Jsonb"
},
{
"ordinal": 8,
"ordinal": 7,
"name": "error",
"type_info": "Text"
},
{
"ordinal": 9,
"ordinal": 8,
"name": "created_at",
"type_info": "Timestamptz"
},
{
"ordinal": 10,
"ordinal": 9,
"name": "updated_at",
"type_info": "Timestamptz"
}
@@ -92,7 +87,6 @@
false,
false,
false,
false,
true,
true,
true,
@@ -100,5 +94,5 @@
false
]
},
"hash": "d827916bb4209968c25769420412953ca44008abaca10dcb7821b78b3db4a0e7"
"hash": "bac545933a627a62b7845d8aab80702443285e4d1d11e5a0f4cd2a3d4add51bb"
}
@@ -1 +1,9 @@
ALTER TABLE native_trigger ADD COLUMN webhook_token_prefix VARCHAR(10) NOT NULL DEFAULT '';
-- Backfill prefix from the token table
UPDATE native_trigger nt
SET webhook_token_prefix = t.token_prefix
FROM token t
WHERE t.token_hash = nt.webhook_token_hash;
ALTER TABLE native_trigger DROP COLUMN IF EXISTS webhook_token_hash;
@@ -1,6 +1,5 @@
-- Add webhook_token_hash to native_trigger for safe token lookups/deletes.
-- The existing webhook_token_prefix (10 chars) is kept for display but is not
-- unique enough for deletion.
-- Add webhook_token_hash to native_trigger for safe token lookups/deletes,
-- and drop webhook_token_prefix which is no longer needed.
ALTER TABLE native_trigger ADD COLUMN webhook_token_hash VARCHAR(64);
@@ -12,3 +11,5 @@ WHERE t.token_prefix = nt.webhook_token_prefix;
-- New triggers will always have a hash, but existing ones might not
-- if their token was already deleted. Leave those NULL.
ALTER TABLE native_trigger DROP COLUMN webhook_token_prefix;
+1 -1
View File
@@ -122,7 +122,7 @@ mcp_oauth_server_code: code(char), client_id(char), user_email(char), workspace_
FK: (client_id) -> mcp_oauth_server_client(client_id)
metrics: id(char), value(jsonb), created_at(ts)
mqtt_trigger: mqtt_resource_path(char), subscribe_topics(jsonb[]), client_version(mqtt_client_version), v5_config(jsonb), v3_config(jsonb), client_id(char), path(char), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), server_id(char), last_server_ping(ts), error(text), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), mode(trigger_mode)
native_trigger: external_id(char), workspace_id(char), service_name(native_trigger_service), script_path(char), is_flow(bool), webhook_token_prefix(char), service_config(jsonb), error(text), created_at(ts), updated_at(ts)
native_trigger: external_id(char), workspace_id(char), service_name(native_trigger_service), script_path(char), is_flow(bool), webhook_token_hash(char), service_config(jsonb), error(text), created_at(ts), updated_at(ts)
FK: (workspace_id) -> workspace(id)
nats_trigger: path(char), nats_resource_path(char), subjects(char), stream_name(char), consumer_name(char), use_jetstream(bool), script_path(char), is_flow(bool), workspace_id(char), edited_by(char), email(char), edited_at(ts), extra_perms(jsonb), server_id(char), last_server_ping(ts), error(text), error_handler_path(char), error_handler_args(jsonb), retry(jsonb), mode(trigger_mode)
FK: (workspace_id) -> workspace(id)
@@ -829,7 +829,7 @@ pub(crate) async fn tarball_workspace(
let trigger_str = &to_string_without_metadata(
&trigger,
false,
Some(vec!["webhook_token_prefix", "webhook_token_hash"]),
Some(vec!["webhook_token_hash"]),
)
.unwrap();
archive
+9 -22
View File
@@ -190,7 +190,6 @@ pub struct NativeTrigger {
pub service_name: ServiceName,
pub script_path: String,
pub is_flow: bool,
pub webhook_token_prefix: String,
pub webhook_token_hash: Option<String>,
pub service_config: Option<serde_json::Value>,
pub error: Option<String>,
@@ -787,9 +786,8 @@ pub async fn store_native_trigger<'c, E: sqlx::Executor<'c, Database = Postgres>
config: &NativeTriggerConfig,
service_config: C,
) -> Result<()> {
use windmill_common::auth::{hash_token, TOKEN_PREFIX_LEN};
use windmill_common::auth::hash_token;
let webhook_token_prefix: String = config.webhook_token[..TOKEN_PREFIX_LEN].to_string();
let webhook_token_hash = hash_token(&config.webhook_token);
sqlx::query!(
@@ -800,21 +798,19 @@ pub async fn store_native_trigger<'c, E: sqlx::Executor<'c, Database = Postgres>
service_name,
script_path,
is_flow,
webhook_token_prefix,
webhook_token_hash,
service_config
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8
$1, $2, $3, $4, $5, $6, $7
)
ON CONFLICT (external_id, workspace_id, service_name)
DO UPDATE SET script_path = $4, is_flow = $5, webhook_token_prefix = $6, webhook_token_hash = $7, service_config = $8, error = NULL, updated_at = NOW()
DO UPDATE SET script_path = $4, is_flow = $5, webhook_token_hash = $6, service_config = $7, error = NULL, updated_at = NOW()
"#,
external_id,
workspace_id,
service_name as ServiceName,
config.script_path,
config.is_flow,
webhook_token_prefix,
webhook_token_hash,
sqlx::types::Json(service_config) as _,
)
@@ -832,23 +828,21 @@ pub async fn update_native_trigger<'c, E: sqlx::Executor<'c, Database = Postgres
config: &NativeTriggerConfig,
service_config: Option<&RawValue>,
) -> Result<()> {
use windmill_common::auth::{hash_token, TOKEN_PREFIX_LEN};
use windmill_common::auth::hash_token;
let webhook_token_prefix: String = config.webhook_token[..TOKEN_PREFIX_LEN].to_string();
let webhook_token_hash = hash_token(&config.webhook_token);
sqlx::query!(
r#"
UPDATE native_trigger
SET script_path = $1, is_flow = $2, webhook_token_prefix = $3, webhook_token_hash = $4, service_config = $5, error = NULL, updated_at = NOW()
SET script_path = $1, is_flow = $2, webhook_token_hash = $3, service_config = $4, error = NULL, updated_at = NOW()
WHERE
workspace_id = $6
AND service_name = $7
AND external_id = $8
workspace_id = $5
AND service_name = $6
AND external_id = $7
"#,
config.script_path,
config.is_flow,
webhook_token_prefix,
webhook_token_hash,
service_config.map(sqlx::types::Json) as _,
workspace_id,
@@ -900,7 +894,6 @@ pub async fn get_native_trigger<'c, E: sqlx::Executor<'c, Database = Postgres>>(
service_name AS "service_name!: ServiceName",
script_path,
is_flow,
webhook_token_prefix,
webhook_token_hash,
service_config,
error,
@@ -939,7 +932,6 @@ pub async fn get_native_trigger_by_script<'c, E: sqlx::Executor<'c, Database = P
service_name AS "service_name!: ServiceName",
script_path,
is_flow,
webhook_token_prefix,
webhook_token_hash,
service_config,
error,
@@ -986,7 +978,6 @@ pub async fn list_native_triggers<'c, E: sqlx::Executor<'c, Database = Postgres>
nt.service_name AS "service_name!: ServiceName",
nt.script_path,
nt.is_flow,
nt.webhook_token_prefix,
nt.webhook_token_hash,
nt.service_config,
nt.error,
@@ -1066,16 +1057,13 @@ pub async fn update_native_trigger_service_config<
service_config: &serde_json::Value,
new_webhook_token: Option<&str>,
) -> Result<()> {
let new_prefix =
new_webhook_token.map(|t| t[..windmill_common::auth::TOKEN_PREFIX_LEN].to_string());
let new_hash = new_webhook_token.map(windmill_common::auth::hash_token);
sqlx::query!(
r#"
UPDATE native_trigger
SET service_config = $1,
webhook_token_prefix = COALESCE($5, webhook_token_prefix),
webhook_token_hash = COALESCE($6, webhook_token_hash),
webhook_token_hash = COALESCE($5, webhook_token_hash),
updated_at = NOW()
WHERE
workspace_id = $2
@@ -1086,7 +1074,6 @@ pub async fn update_native_trigger_service_config<
workspace_id,
service_name as ServiceName,
external_id,
new_prefix.as_deref(),
new_hash.as_deref(),
)
.execute(db)