feat(cloudron): add tirreno package artifacts

- Add CloudronStack/output/CloudronPackages-Artifacts/tirreno/ directory and its contents
- Includes package manifest, Dockerfile, source code, documentation, and build artifacts
- Add tirreno-1761840148.tar.gz as a build artifact
- Add tirreno-cloudron-package-1761841304.tar.gz as the Cloudron package
- Include all necessary files for the tirreno Cloudron package

This adds the complete tirreno Cloudron package artifacts to the repository.
This commit is contained in:
2025-10-30 11:43:06 -05:00
parent 0ce353ea9d
commit 91d52d2de5
1692 changed files with 202851 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
<?php
/**
* Tirreno ~ Open source user analytics
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
*
* Licensed under GNU Affero General Public License version 3 of the or any later version.
* For full copyright and license information, please see the LICENSE
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
* @link https://www.tirreno.com Tirreno(tm)
*/
namespace Updates;
abstract class Base {
public static $version = '';
abstract public static function apply($db);
public static function isApplied($updatesModel) {
return $updatesModel->isApplied(static::$version, 'core');
}
}

View File

@@ -0,0 +1,30 @@
<?php
/**
* Tirreno ~ Open source user analytics
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
*
* Licensed under GNU Affero General Public License version 3 of the or any later version.
* For full copyright and license information, please see the LICENSE
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
* @link https://www.tirreno.com Tirreno(tm)
*/
namespace Updates;
class Update001 extends Base {
public static $version = 'v0.9.5';
public static function apply($db) {
$queries = [
'ALTER TABLE dshb_api ADD COLUMN blacklist_threshold INTEGER DEFAULT -1',
'ALTER TABLE dshb_api ADD COLUMN review_queue_threshold INTEGER DEFAULT 33',
];
foreach ($queries as $sql) {
$db->exec($sql);
}
}
}

View File

@@ -0,0 +1,258 @@
<?php
/**
* Tirreno ~ Open source user analytics
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
*
* Licensed under GNU Affero General Public License version 3 of the or any later version.
* For full copyright and license information, please see the LICENSE
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
* @link https://www.tirreno.com Tirreno(tm)
*/
namespace Updates;
class Update002 extends Base {
public static $version = 'v0.9.6';
private static $rulesMap = [
29 => 'E20',
24 => 'B19',
19 => 'B04',
44 => 'E27',
4 => 'B07',
1 => 'I01',
9 => 'E19',
99 => 'E05',
82 => 'E10',
10 => 'D06',
15 => 'E13',
2 => 'I06',
102 => 'E08',
84 => 'P02',
23 => 'I08',
63 => 'D02',
100 => 'E06',
7 => 'E12',
87 => 'B08',
74 => 'E24',
20 => 'B05',
46 => 'C01',
8 => 'E16',
3 => 'E01',
109 => 'B23',
16 => 'A01',
25 => 'D07',
11 => 'B01',
65 => 'D03',
67 => 'A03',
54 => 'C08',
50 => 'C04',
17 => 'B02',
81 => 'D08',
47 => 'C02',
62 => 'D01',
18 => 'B03',
22 => 'B06',
14 => 'E11',
72 => 'A08',
86 => 'E15',
35 => 'C16',
12 => 'I09',
5 => 'E17',
6 => 'E02',
106 => 'R03',
48 => 'P04',
104 => 'R01',
105 => 'R02',
41 => 'B20',
45 => 'E28',
88 => 'B09',
97 => 'E03',
77 => 'B12',
78 => 'D09',
85 => 'P01',
94 => 'B16',
57 => 'I03',
40 => 'B18',
58 => 'B21',
69 => 'A05',
75 => 'E25',
89 => 'B10',
83 => 'E14',
31 => 'E22',
80 => 'B14',
73 => 'E23',
96 => 'P03',
68 => 'A04',
101 => 'E07',
64 => 'I04',
26 => 'D04',
27 => 'D05',
79 => 'E26',
95 => 'B13',
53 => 'C07',
43 => 'I11',
37 => 'E29',
71 => 'A07',
66 => 'A02',
93 => 'B15',
30 => 'E21',
60 => 'I02',
59 => 'I05',
42 => 'B17',
76 => 'B11',
38 => 'E30',
61 => 'I07',
28 => 'I10',
39 => 'D10',
70 => 'A06',
98 => 'E04',
21 => 'C11',
103 => 'E09',
49 => 'C03',
52 => 'C06',
108 => 'I12',
33 => 'C14',
55 => 'C09',
56 => 'C10',
32 => 'C13',
36 => 'C12',
107 => 'B22',
51 => 'C05',
34 => 'C15',
110 => 'B24',
];
public static function apply($db) {
$queries = [
'INSERT INTO dshb_rules (id) VALUES (109), (110)',
'CREATE INDEX event_account_lastseen_key_idx ON event_account USING btree (lastseen, key)',
'CREATE INDEX event_url_lastseen_key_idx ON event_url USING btree (lastseen, key)',
'CREATE INDEX event_time_key_idx ON event USING btree (time, key)',
'CREATE INDEX event_account_latest_decision_key_idx ON event_account USING btree (latest_decision, key)',
'CREATE INDEX event_country_lastseen_key_idx ON event_country USING btree (lastseen, key)',
'CREATE INDEX event_ip_lastseen_key_idx ON event_ip USING btree (lastseen, key)',
'ALTER TABLE dshb_rules ADD COLUMN validated BOOLEAN NOT NULL DEFAULT false',
'ALTER TABLE dshb_rules ADD COLUMN uid VARCHAR',
'ALTER TABLE dshb_rules ADD COLUMN name VARCHAR',
'ALTER TABLE dshb_rules ADD COLUMN descr VARCHAR',
'ALTER TABLE dshb_rules ADD COLUMN attributes JSONB DEFAULT \'[]\' NOT NULL',
'ALTER TABLE dshb_rules ADD COLUMN updated TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL',
'ALTER TABLE dshb_rules ADD COLUMN missing BOOLEAN',
'DELETE FROM dshb_rules WHERE id IN (13, 90, 91, 92)',
'UPDATE event_error_type SET name = \'Success\' WHERE id = 0',
'UPDATE event_error_type SET name = \'Success with warnings\' WHERE id = 1',
];
foreach ($queries as $sql) {
$db->exec($sql);
}
$sql = 'SELECT id FROM dshb_rules';
$rulesIds = array_column($db->exec($sql), 'id');
$rules = self::extendIds($rulesIds);
// extend rules data
foreach ($rules as $id => $rule) {
$params = [
':validated' => true,
':id' => $id,
':uid' => $rule['uid'],
':name' => $rule['name'],
':descr' => $rule['descr'],
':attributes' => json_encode($rule['attributes']),
];
$query = (
'INSERT INTO dshb_rules (id, uid, name, descr, validated, attributes)
VALUES (:id, :uid, :name, :descr, :validated, :attributes)
ON CONFLICT (id) DO UPDATE
SET uid = EXCLUDED.uid, name = EXCLUDED.name, descr = EXCLUDED.descr,
validated = EXCLUDED.validated, attributes = EXCLUDED.attributes'
);
$db->exec($query, $params);
}
// add uid to dshb_operators_rules
$sql = 'ALTER TABLE dshb_operators_rules ADD COLUMN rule_uid VARCHAR';
$db->exec($sql);
foreach ($rulesIds as $id) {
$sql = 'UPDATE dshb_operators_rules SET rule_uid = :uid WHERE rule_id = :id';
$db->exec($sql, [':id' => $id, ':uid' => self::$rulesMap[$id]]);
}
// update event_account score details
$sql = 'ALTER TABLE event_account ALTER COLUMN score_details TYPE JSONB USING score_details::jsonb';
$db->exec($sql);
$sql = (
'UPDATE event_account
SET score_details = (
SELECT jsonb_agg((elem - \'id\') || jsonb_build_object(\'uid\', dshb_rules.uid))
FROM jsonb_array_elements(score_details) AS elem
JOIN dshb_rules
ON (elem->>\'id\')::int = dshb_rules.id
)
WHERE event_account.score_details IS NOT NULL'
);
$db->exec($sql);
// cleanup
$queries = [
'ALTER TABLE dshb_operators_rules DROP COLUMN rule_id',
'ALTER TABLE dshb_rules ALTER COLUMN uid SET NOT NULL',
'ALTER TABLE dshb_rules ALTER COLUMN name SET NOT NULL',
'ALTER TABLE dshb_rules ALTER COLUMN descr SET NOT NULL',
'ALTER TABLE dshb_rules DROP COLUMN id',
'ALTER TABLE dshb_rules ADD CONSTRAINT dshb_rules_uid_pkey PRIMARY KEY (uid)',
'ALTER TABLE dshb_operators_rules ADD CONSTRAINT dshb_operators_rules_rule_uid_fkey FOREIGN KEY (rule_uid) REFERENCES dshb_rules(uid) ON DELETE CASCADE',
'CREATE INDEX event_account_score_details_idx ON event_account USING GIN (score_details)',
];
foreach ($queries as $sql) {
$db->exec($sql);
}
}
public static function extendIds(array $ids): array {
$results = [];
$rules = self::getCoreRulesMetadata();
foreach ($ids as $id) {
$uid = self::$rulesMap[$id];
if (isset($rules[$uid])) {
$results[$id] = $rules[$uid];
}
}
return $results;
}
private static function getCoreRulesMetadata(): array {
$rules = \Utils\RulesClasses::getRulesClasses(true);
$out = [];
foreach ($rules['imported'] as $uid => $cls) {
try {
$out[$uid] = [
'uid' => $uid,
'name' => $cls::NAME,
'descr' => $cls::DESCRIPTION,
'attributes' => $cls::ATTRIBUTES,
];
} catch (\Throwable $e) {
error_log('Fail on const call: ' . $e->getMessage());
}
}
return $out;
}
}

View File

@@ -0,0 +1,67 @@
<?php
/**
* Tirreno ~ Open source user analytics
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
*
* Licensed under GNU Affero General Public License version 3 of the or any later version.
* For full copyright and license information, please see the LICENSE
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
* @link https://www.tirreno.com Tirreno(tm)
*/
namespace Updates;
class Update003 extends Base {
public static $version = 'v0.9.7';
public static function apply($db) {
$data = [':type' => \Utils\Constants::get('PAGE_ERROR_EVENT_TYPE_ID')];
$queries = [
'ALTER TABLE event_logbook DROP COLUMN raw_time',
'ALTER TABLE event_account ADD COLUMN added_to_review TIMESTAMP WITHOUT TIME ZONE DEFAULT NULL',
'CREATE INDEX event_account_added_to_review_idx ON event_account USING btree (added_to_review)',
(
'UPDATE event_account
SET added_to_review = event_account.lastseen
FROM dshb_api
WHERE
event_account.key = dshb_api.id AND
event_account.fraud IS NULL AND
event_account.score <= dshb_api.review_queue_threshold'
),
];
foreach ($queries as $sql) {
$db->exec($sql);
}
$sql = 'INSERT INTO event_type (id, value, name) VALUES (:type, \'page_error\', \'Page Error\')';
$db->exec($sql, $data);
$queries = [
'ALTER TABLE countries RENAME COLUMN id TO iso',
'ALTER TABLE countries RENAME COLUMN serial TO id',
'ALTER TABLE countries DROP CONSTRAINT countries_id_pkey',
'DROP INDEX countries_serial_uidx',
'ALTER TABLE countries ADD CONSTRAINT countries_id_pkey PRIMARY KEY (id)',
'CREATE UNIQUE INDEX countries_iso_uidx ON countries USING btree (iso)',
];
foreach ($queries as $sql) {
$db->exec($sql);
}
$sql = (
'UPDATE event
SET type = :type
WHERE http_code >= 400'
);
$db->exec($sql, $data);
}
}

View File

@@ -0,0 +1,88 @@
<?php
/**
* Tirreno ~ Open source user analytics
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
*
* Licensed under GNU Affero General Public License version 3 of the or any later version.
* For full copyright and license information, please see the LICENSE
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
* @link https://www.tirreno.com Tirreno(tm)
*/
namespace Updates;
class Update004 extends Base {
public static $version = 'v0.9.8';
public static function apply($db) {
$data = [':type' => \Utils\Constants::get('FIELD_EDIT_EVENT_TYPE_ID')];
$queries = [
('CREATE SEQUENCE event_field_audit_trail_id_seq
AS BIGINT
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
'),
('CREATE TABLE event_field_audit_trail (
id BIGINT NOT NULL DEFAULT nextval(\'event_field_audit_trail_id_seq\'::regclass),
account_id BIGINT NOT NULL,
key smallint NOT NULL,
created timestamp without time zone DEFAULT CURRENT_TIMESTAMP,
event_id BIGINT,
field_id varchar,
field_name varchar,
old_value varchar,
new_value varchar,
parent_id varchar,
parent_name varchar
)'),
'ALTER SEQUENCE event_field_audit_trail_id_seq OWNED BY event_field_audit_trail.id',
'CREATE INDEX event_field_audit_trail_account_id_idx ON event_field_audit_trail USING btree (account_id)',
'CREATE INDEX event_field_audit_trail_key_idx ON event_field_audit_trail USING btree (key)',
'ALTER TABLE ONLY event_field_audit_trail ADD CONSTRAINT event_field_audit_trail_id_pkey PRIMARY KEY (id)',
];
foreach ($queries as $sql) {
$db->exec($sql);
}
$sql = 'INSERT INTO event_type (id, value, name) VALUES (:type, \'field_edit\', \'Field Edit\')';
$db->exec($sql, $data);
$queries = [
('CREATE SEQUENCE event_payload_id_seq
AS BIGINT
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
'),
('CREATE TABLE event_payload (
id BIGINT NOT NULL DEFAULT nextval(\'event_payload_id_seq\'::regclass),
key smallint NOT NULL,
created timestamp without time zone DEFAULT CURRENT_TIMESTAMP,
payload json
)'),
'ALTER SEQUENCE event_payload_id_seq OWNED BY event_payload.id',
'CREATE INDEX event_payload_created_idx ON event_payload USING btree (created)',
'CREATE INDEX event_payload_key_idx ON event_payload USING btree (key)',
'ALTER TABLE ONLY event_payload ADD CONSTRAINT event_payload_id_pkey PRIMARY KEY (id)',
'ALTER TABLE event DROP COLUMN payload',
'ALTER TABLE event ADD COLUMN payload BIGINT',
'CREATE INDEX event_payload_idx ON event USING btree (payload)',
'ALTER TABLE ONLY event ADD CONSTRAINT event_payload_fkey FOREIGN KEY (payload) REFERENCES event_payload(id)',
];
foreach ($queries as $sql) {
$db->exec($sql);
}
}
}

View File

@@ -0,0 +1,66 @@
<?php
/**
* Tirreno ~ Open source user analytics
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
*
* Licensed under GNU Affero General Public License version 3 of the or any later version.
* For full copyright and license information, please see the LICENSE
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
* @link https://www.tirreno.com Tirreno(tm)
*/
namespace Updates;
class Update005 extends Base {
public static $version = 'v0.9.9';
public static function apply($db) {
$queries = [
'CREATE INDEX event_ua_parsed_device_idx ON event_ua_parsed USING btree (device)',
'ALTER TABLE event_device DROP CONSTRAINT event_device_account_id_key_user_agent_key',
'ALTER TABLE ONLY event_device ADD CONSTRAINT event_device_account_id_key_user_agent_lang_key UNIQUE (account_id, key, user_agent, lang)',
('CREATE SEQUENCE event_session_stat_id_seq
AS BIGINT
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
'),
('CREATE TABLE event_session_stat (
id BIGINT NOT NULL DEFAULT nextval(\'event_session_stat_id_seq\'::regclass),
session_id BIGINT NOT NULL,
-- account_id BIGINT NOT NULL,
key smallint NOT NULL,
created timestamp without time zone DEFAULT CURRENT_TIMESTAMP,
updated timestamp without time zone DEFAULT CURRENT_TIMESTAMP,
-- started timestamp without time zone NOT NULL,
-- ended timestamp without time zone,
duration integer,
ip_count integer,
device_count integer,
event_count integer,
country_count integer,
new_ip_count integer,
new_device_count integer,
http_codes jsonb DEFAULT \'[]\'::jsonb,
http_methods jsonb DEFAULT \'[]\'::jsonb,
event_types jsonb DEFAULT \'[]\'::jsonb,
completed boolean DEFAULT FALSE
)'),
'ALTER SEQUENCE event_session_stat_id_seq OWNED BY event_session_stat.id',
//'CREATE INDEX event_session_stat_account_id_idx ON event_session_stat USING btree (account_id)',
'CREATE UNIQUE INDEX event_session_stat_session_id_uidx ON event_session_stat USING btree (session_id)',
'CREATE INDEX event_session_stat_key_idx ON event_session_stat USING btree (key)',
'ALTER TABLE ONLY event_session_stat ADD CONSTRAINT event_session_stat_id_pkey PRIMARY KEY (id)',
];
foreach ($queries as $sql) {
$db->exec($sql);
}
}
}

View File

@@ -0,0 +1,3 @@
<?php
//