Files
cloudron-box/migrations/schema.sql
T

347 lines
13 KiB
SQL
Raw Normal View History

#### WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
#### This file is not used by any code and is here to document the latest schema
#### General ideas
#### Default char set is utf8 and DEFAULT COLLATE is utf8_bin. Collate affects comparisons in WHERE and ORDER
#### Strict mode is enabled
#### VARCHAR - stored as part of table row (use for strings)
#### TEXT - stored offline from table row (use for strings)
2021-04-29 12:49:48 -07:00
#### BLOB (64KB), MEDIUMBLOB (16MB), LONGBLOB (4GB) - stored offline from table row (use for binary data)
#### https://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html
2019-03-23 09:46:04 -07:00
#### Times are stored in the database in UTC. And precision is seconds
2017-11-19 12:36:05 -08:00
# The code uses zero dates. Make sure sql_mode does NOT have NO_ZERO_DATE
# http://johnemb.blogspot.com/2014/09/adding-or-removing-individual-sql-modes.html
# SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'NO_ZERO_DATE',''));
CREATE TABLE IF NOT EXISTS users(
id VARCHAR(128) NOT NULL UNIQUE,
2016-04-05 10:54:09 +02:00
username VARCHAR(254) UNIQUE,
email VARCHAR(254) NOT NULL UNIQUE,
password VARCHAR(1024) NOT NULL,
salt VARCHAR(512) NOT NULL,
2021-05-17 07:18:21 -07:00
creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
2020-07-09 15:43:22 -07:00
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
2018-04-25 16:33:18 +02:00
displayName VARCHAR(512) DEFAULT "",
fallbackEmail VARCHAR(512) DEFAULT "",
twoFactorAuthenticationSecret VARCHAR(128) DEFAULT "",
twoFactorAuthenticationEnabled BOOLEAN DEFAULT false,
2019-08-29 17:52:00 +02:00
source VARCHAR(128) DEFAULT "",
role VARCHAR(32),
2021-10-01 12:27:22 +02:00
inviteToken VARCHAR(128) DEFAULT "",
2020-03-30 16:32:28 -07:00
resetToken VARCHAR(128) DEFAULT "",
2020-03-30 16:47:18 -07:00
resetTokenCreationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
2020-03-30 16:32:28 -07:00
active BOOLEAN DEFAULT 1,
avatar MEDIUMBLOB NOT NULL,
2022-05-14 19:41:32 +02:00
backgroundImage MEDIUMBLOB,
2021-08-20 10:30:14 -07:00
loginLocationsJson MEDIUMTEXT, // { locations: [{ ip, userAgent, city, country, ts }] }
2024-12-11 18:24:20 +01:00
notificationConfigJson TEXT,
2018-01-21 14:25:39 +01:00
2021-05-17 07:18:21 -07:00
INDEX creationTime_index (creationTime),
PRIMARY KEY(id));
2018-12-01 00:38:00 +01:00
CREATE TABLE IF NOT EXISTS userGroups(
2016-02-07 19:24:07 -08:00
id VARCHAR(128) NOT NULL UNIQUE,
2016-09-27 21:11:41 +02:00
name VARCHAR(254) NOT NULL UNIQUE,
2020-06-04 13:25:55 +02:00
source VARCHAR(128) DEFAULT "",
2016-02-07 19:24:07 -08:00
PRIMARY KEY(id));
2016-02-08 08:55:37 -08:00
CREATE TABLE IF NOT EXISTS groupMembers(
groupId VARCHAR(128) NOT NULL,
userId VARCHAR(128) NOT NULL,
2018-12-01 00:38:00 +01:00
FOREIGN KEY(groupId) REFERENCES userGroups(id),
2020-12-22 10:34:19 -08:00
FOREIGN KEY(userId) REFERENCES users(id),
UNIQUE (groupId, userId));
2016-02-08 08:55:37 -08:00
CREATE TABLE IF NOT EXISTS tokens(
2019-02-15 13:57:18 -08:00
id VARCHAR(128) NOT NULL UNIQUE,
2018-08-27 14:50:41 -07:00
name VARCHAR(64) DEFAULT "", // description
accessToken VARCHAR(128) NOT NULL UNIQUE,
2019-02-15 13:57:18 -08:00
identifier VARCHAR(128) NOT NULL, // resourceId: app id or user id
clientId VARCHAR(128),
2022-09-22 21:58:56 +02:00
scopeJson TEXT,
expires BIGINT NOT NULL, // FIXME: make this a timestamp
2021-03-15 12:47:57 -07:00
lastUsedTime TIMESTAMP NULL,
2025-03-07 11:53:03 +01:00
allowedIpRanges TEXT NULL,
PRIMARY KEY(accessToken));
CREATE TABLE IF NOT EXISTS apps(
id VARCHAR(128) NOT NULL UNIQUE,
2019-11-16 10:31:32 -08:00
appStoreId VARCHAR(128) NOT NULL, // empty for custom apps
2019-09-22 00:20:12 -07:00
installationState VARCHAR(512) NOT NULL, // the active task on the app
2019-09-22 22:07:14 -07:00
runState VARCHAR(512) NOT NULL, // if the app is stopped
health VARCHAR(128),
2019-02-12 16:03:12 -08:00
healthTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, // when the app last responded
containerId VARCHAR(128),
manifestJson TEXT,
2016-05-27 11:10:36 -07:00
accessRestrictionJson TEXT, // { users: [ ], groups: [ ] }
creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, // when the app was installed
updateTime TIMESTAMP NULL DEFAULT NULL, // when the last app update was done . Without the first NULL, it comes current time when assigned null!
2018-06-26 18:09:04 -07:00
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, // when this db record was updated (useful for UI caching)
2016-02-05 15:03:45 +01:00
memoryLimit BIGINT DEFAULT 0,
2024-04-10 17:38:49 +02:00
cpuQuota INTEGER DEFAULT 100,
2016-07-14 15:04:52 +02:00
xFrameOptions VARCHAR(512),
2016-11-11 10:48:33 +05:30
sso BOOLEAN DEFAULT 1, // whether user chose to enable SSO
2024-12-05 13:47:59 +01:00
devicesJson TEXT,
debugModeJson TEXT, // options for development mode
2023-03-06 11:15:55 +01:00
reverseProxyConfigJson TEXT, // { robotsTxt, csp, hstsPreload }
2017-11-21 18:09:44 -08:00
enableBackup BOOLEAN DEFAULT 1, // misnomer: controls automatic daily backups
2018-12-07 09:03:28 -08:00
enableAutomaticUpdate BOOLEAN DEFAULT 1,
2021-03-16 22:38:59 -07:00
enableMailbox BOOLEAN DEFAULT 1, // whether sendmail addon is enabled
2020-03-30 22:18:39 -07:00
mailboxName VARCHAR(128), // mailbox of this app
2022-06-01 22:06:34 -07:00
mailboxDomain VARCHAR(128), // mailbox domain of this app
mailboxDisplayName VARCHAR(128), // mailbox display name
2021-10-01 12:09:13 -07:00
enableInbox BOOLEAN DEFAULT 0, // whether recvmail addon is enabled
inboxName VARCHAR(128), // mailbox of this app
2022-06-01 22:06:34 -07:00
inboxDomain VARCHAR(128), // mailbox domain of this app
2019-03-22 14:09:31 -07:00
label VARCHAR(128), // display name
2024-04-10 17:02:32 +02:00
notes TEXT, // free form notes for admins
2019-03-22 14:09:31 -07:00
tagsJson VARCHAR(2048), // array of tags
2022-06-01 22:44:52 -07:00
storageVolumeId VARCHAR(128),
storageVolumePrefix VARCHAR(128),
2019-08-26 14:12:36 -07:00
taskId INTEGER, // current task
2019-08-30 09:45:43 -07:00
errorJson TEXT,
2020-06-26 15:48:39 -07:00
servicesConfigJson TEXT, // app services configuration
2020-11-20 14:13:16 -08:00
containerIp VARCHAR(16) UNIQUE, // this is not-null because of ip allocation fails, user can 'repair'
2021-04-30 13:18:15 -07:00
appStoreIcon MEDIUMBLOB,
icon MEDIUMBLOB,
2021-12-03 11:40:55 -08:00
crontab TEXT,
2022-06-08 11:21:09 +02:00
upstreamUri VARCHAR(256) DEFAULT "",
2024-04-17 16:54:54 +02:00
checklistJson TEXT, // checklist for admins
2019-11-14 21:43:14 -08:00
FOREIGN KEY(mailboxDomain) REFERENCES domains(domain),
2024-02-27 13:45:08 +01:00
FOREIGN KEY(inboxDomain) REFERENCES domains(domain),
2019-08-26 14:12:36 -07:00
FOREIGN KEY(taskId) REFERENCES tasks(id),
2022-06-01 22:44:52 -07:00
FOREIGN KEY(storageVolumeId) REFERENCES volumes(id),
UNIQUE (storageVolumeId, storageVolumePrefix),
PRIMARY KEY(id));
CREATE TABLE IF NOT EXISTS appPortBindings(
hostPort INTEGER NOT NULL UNIQUE,
2018-08-12 22:08:19 -07:00
type VARCHAR(8) NOT NULL DEFAULT "tcp",
environmentVariable VARCHAR(128) NOT NULL,
appId VARCHAR(128) NOT NULL,
2024-07-16 22:21:36 +02:00
count INTEGER NOT NULL DEFAULT 1,
FOREIGN KEY(appId) REFERENCES apps(id),
PRIMARY KEY(hostPort));
CREATE TABLE IF NOT EXISTS settings(
name VARCHAR(128) NOT NULL UNIQUE,
2017-09-11 15:35:55 +02:00
value TEXT,
2021-04-29 15:46:11 -07:00
valueBlob MEDIUMBLOB,
PRIMARY KEY(name));
CREATE TABLE IF NOT EXISTS appAddonConfigs(
appId VARCHAR(128) NOT NULL,
addonId VARCHAR(32) NOT NULL,
2017-03-25 13:35:28 -07:00
name VARCHAR(128) NOT NULL,
2021-08-09 13:40:23 -07:00
value TEXT NOT NULL,
FOREIGN KEY(appId) REFERENCES apps(id));
2018-10-11 14:07:43 -07:00
CREATE TABLE IF NOT EXISTS appEnvVars(
appId VARCHAR(128) NOT NULL,
name TEXT NOT NULL,
value TEXT NOT NULL,
FOREIGN KEY(appId) REFERENCES apps(id));
2016-03-07 09:26:26 -08:00
CREATE TABLE IF NOT EXISTS backups(
2017-05-26 22:23:24 -07:00
id VARCHAR(128) NOT NULL,
2022-04-04 14:13:27 -07:00
remotePath VARCHAR(256) NOT NULL UNIQUE,
label VARCHAR(128) DEFAULT "",
creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
2020-05-13 22:09:33 -07:00
packageVersion VARCHAR(128) NOT NULL, /* app version or box version */
encryptionVersion INTEGER, /* when null, unencrypted backup */
2016-03-07 09:26:26 -08:00
type VARCHAR(16) NOT NULL, /* 'box' or 'app' */
2020-06-14 11:29:07 -07:00
identifier VARCHAR(128) NOT NULL, /* 'box' or the app id */
2022-04-04 14:13:27 -07:00
dependsOnJson TEXT, /* comma separate list of objects this backup depends on */
2016-03-07 09:26:26 -08:00
state VARCHAR(16) NOT NULL,
manifestJson TEXT, /* to validate if the app can be installed in this version of box */
format VARCHAR(16) DEFAULT "tgz",
2019-04-13 17:09:15 -07:00
preserveSecs INTEGER DEFAULT 0,
2024-12-10 20:52:29 +01:00
appConfigJson TEXT, /* useful for clone and archive */
2016-03-07 09:26:26 -08:00
INDEX creationTime_index (creationTime),
2017-05-26 22:23:24 -07:00
PRIMARY KEY (id));
2016-04-29 23:28:54 -07:00
2024-12-10 10:06:52 +01:00
CREATE TABLE IF NOT EXISTS archives(
id VARCHAR(128) NOT NULL UNIQUE,
backupId VARCHAR(128) NOT NULL,
creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
appStoreIcon MEDIUMBLOB,
icon MEDIUMBLOB,
FOREIGN KEY(backupId) REFERENCES backups(id),
PRIMARY KEY (id));
2016-04-29 23:28:54 -07:00
CREATE TABLE IF NOT EXISTS eventlog(
id VARCHAR(128) NOT NULL,
action VARCHAR(128) NOT NULL,
2021-11-17 12:21:46 -08:00
sourceJson TEXT, /* { userId, username, ip }. userId can be null for cron,sysadmin */
dataJson TEXT, /* free flowing json based on action */
creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
2016-04-29 23:28:54 -07:00
INDEX creationTime_index (creationTime),
2016-04-29 23:28:54 -07:00
PRIMARY KEY (id));
2016-05-26 18:02:22 -07:00
2017-10-27 23:39:53 +02:00
CREATE TABLE IF NOT EXISTS domains(
2017-10-30 00:16:33 +01:00
domain VARCHAR(128) NOT NULL UNIQUE, /* if this needs to be larger, InnoDB has a limit of 767 bytes for PRIMARY KEY values! */
2017-10-27 23:39:53 +02:00
zoneName VARCHAR(128) NOT NULL, /* this mostly contains the domain itself again */
2018-01-09 14:46:38 -08:00
provider VARCHAR(16) NOT NULL,
2017-10-27 23:39:53 +02:00
configJson TEXT, /* JSON containing the dns backend provider config */
tlsConfigJson TEXT, /* JSON containing the tls provider config */
2020-12-23 15:34:23 -08:00
wellKnownJson TEXT, /* JSON containing well known docs for this domain */
2017-10-27 23:39:53 +02:00
fallbackCertificateJson MEDIUMTEXT,
2021-05-04 21:40:11 -07:00
2017-10-30 00:16:33 +01:00
PRIMARY KEY (domain))
/* the default db collation is utf8mb4_unicode_ci but for the app table domain constraint we have to use the old one */
CHARACTER SET utf8 COLLATE utf8_bin;
2018-01-20 22:17:53 -08:00
2018-01-23 15:45:30 +01:00
CREATE TABLE IF NOT EXISTS mail(
2018-01-20 22:17:53 -08:00
domain VARCHAR(128) NOT NULL UNIQUE,
enabled BOOLEAN DEFAULT 0, /* MDA enabled */
mailFromValidation BOOLEAN DEFAULT 1,
catchAllJson TEXT,
relayJson TEXT,
2020-08-23 14:33:58 -07:00
bannerJson TEXT,
2018-01-20 22:17:53 -08:00
2021-10-11 19:51:29 -07:00
dkimKeyJson MEDIUMTEXT,
2019-06-10 12:23:29 -07:00
dkimSelector VARCHAR(128) NOT NULL DEFAULT "cloudron",
2018-01-20 22:17:53 -08:00
FOREIGN KEY(domain) REFERENCES domains(domain),
PRIMARY KEY(domain))
CHARACTER SET utf8 COLLATE utf8_bin;
2024-12-03 16:33:59 +01:00
/* NOTE: this table contains only real mailboxes. And has unique constraint to handle
2018-12-06 21:08:19 -08:00
conflict with aliases and mailbox names
*/
CREATE TABLE IF NOT EXISTS mailboxes(
name VARCHAR(128) NOT NULL,
2018-04-07 19:12:07 -07:00
type VARCHAR(16) NOT NULL, /* 'mailbox', 'alias', 'list' */
2018-12-06 21:08:19 -08:00
ownerId VARCHAR(128) NOT NULL, /* user id */
2020-11-12 23:25:33 -08:00
ownerType VARCHAR(16) NOT NULL,
2020-04-19 18:44:16 -07:00
aliasName VARCHAR(128), /* the target name type is an alias */
aliasDomain VARCHAR(128), /* the target domain */
2019-09-11 12:44:15 -07:00
membersJson TEXT, /* members of a group. fully qualified */
2020-04-17 16:55:23 -07:00
membersOnly BOOLEAN DEFAULT false,
creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
domain VARCHAR(128),
active BOOLEAN DEFAULT 1,
enablePop3 BOOLEAN DEFAULT 0,
2022-08-17 23:18:38 +02:00
storageQuota BIGINT DEFAULT 0,
messagesQuota BIGINT DEFAULT 0,
FOREIGN KEY(domain) REFERENCES mail(domain),
2020-04-19 18:44:16 -07:00
FOREIGN KEY(aliasDomain) REFERENCES mail(domain),
UNIQUE (name, domain));
2018-01-20 22:17:53 -08:00
2022-02-07 13:53:24 -08:00
CREATE TABLE IF NOT EXISTS locations(
2018-06-28 19:39:15 +02:00
appId VARCHAR(128) NOT NULL,
domain VARCHAR(128) NOT NULL,
subdomain VARCHAR(128) NOT NULL,
2022-01-14 22:40:51 -08:00
type VARCHAR(128) NOT NULL, /* primary, secondary, redirect, alias */
environmentVariable VARCHAR(128), /* only set for secondary */
2018-06-29 11:29:30 +02:00
certificateJson MEDIUMTEXT,
2018-06-28 19:39:15 +02:00
FOREIGN KEY(domain) REFERENCES domains(domain),
FOREIGN KEY(appId) REFERENCES apps(id),
2018-11-16 11:13:03 -08:00
UNIQUE (subdomain, domain));
CREATE TABLE IF NOT EXISTS tasks(
2018-12-08 18:50:06 -08:00
id int NOT NULL AUTO_INCREMENT,
type VARCHAR(32) NOT NULL,
2021-09-30 09:01:43 -07:00
argsJson TEXT,
2018-11-16 11:13:03 -08:00
percent INTEGER DEFAULT 0,
message TEXT,
2019-08-30 13:46:55 -07:00
errorJson TEXT,
resultJson TEXT,
2018-11-16 11:13:03 -08:00
creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX creationTime_index (creationTime),
2018-11-16 11:13:03 -08:00
PRIMARY KEY (id));
2018-06-29 11:04:14 +02:00
2018-12-17 15:52:52 +01:00
CREATE TABLE IF NOT EXISTS notifications(
id int NOT NULL AUTO_INCREMENT,
eventId VARCHAR(128), // reference to eventlog. can be null
2023-09-22 17:58:13 +02:00
type VARCHAR(128) NOT NULL DEFAULT ""
2018-12-17 15:52:52 +01:00
title VARCHAR(512) NOT NULL,
message TEXT,
acknowledged BOOLEAN DEFAULT false,
creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
2024-12-11 22:29:00 +01:00
context VARCHAR(128) DEFAULT "", // used along with "type" to create uniqueness
INDEX creationTime_index (creationTime),
2021-04-19 21:00:31 -07:00
FOREIGN KEY(eventId) REFERENCES eventlog(id),
2018-12-17 15:52:52 +01:00
PRIMARY KEY (id)
);
2018-11-16 11:13:03 -08:00
2020-01-31 15:28:42 -08:00
CREATE TABLE IF NOT EXISTS appPasswords(
id VARCHAR(128) NOT NULL UNIQUE,
name VARCHAR(128) NOT NULL,
userId VARCHAR(128) NOT NULL,
identifier VARCHAR(128) NOT NULL, // resourceId: app id or mail or webadmin
hashedPassword VARCHAR(1024) NOT NULL,
creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
2021-04-19 21:02:14 -07:00
UNIQUE KEY appPasswords_name_appId_identifier (name, userId, identifier)
2020-01-31 15:28:42 -08:00
FOREIGN KEY(userId) REFERENCES users(id),
2020-01-31 15:28:42 -08:00
PRIMARY KEY (id)
);
2020-10-27 22:39:05 -07:00
CREATE TABLE IF NOT EXISTS volumes(
id VARCHAR(128) NOT NULL UNIQUE,
name VARCHAR(256) NOT NULL UNIQUE,
2023-02-25 23:14:54 +01:00
hostPath VARCHAR(1024) NOT NULL UNIQUE, // computed hostPath
2020-10-27 22:39:05 -07:00
creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
mountType VARCHAR(16) DEFAULT "noop",
mountOptionsJson TEXT,
2020-10-27 22:39:05 -07:00
PRIMARY KEY (id)
);
2020-10-28 19:42:48 -07:00
CREATE TABLE IF NOT EXISTS appMounts(
2020-10-27 22:39:05 -07:00
appId VARCHAR(128) NOT NULL,
volumeId VARCHAR(128) NOT NULL,
2020-10-29 22:08:31 -07:00
readOnly BOOLEAN DEFAULT 1,
UNIQUE KEY appMounts_appId_volumeId (appId, volumeId),
2020-10-27 22:39:05 -07:00
FOREIGN KEY(appId) REFERENCES apps(id),
FOREIGN KEY(volumeId) REFERENCES volumes(id));
2021-04-30 22:26:51 -07:00
CREATE TABLE IF NOT EXISTS blobs(
id VARCHAR(128) NOT NULL UNIQUE,
2022-02-01 17:29:19 -08:00
value MEDIUMBLOB,
2021-04-30 22:26:51 -07:00
PRIMARY KEY(id));
2021-04-30 21:54:53 -07:00
2022-07-06 19:15:59 +02:00
CREATE TABLE IF NOT EXISTS appLinks(
id VARCHAR(128) NOT NULL UNIQUE,
accessRestrictionJson TEXT, // { users: [ ], groups: [ ] }
creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, // when the app was installed
updateTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, // when the last app update was done
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, // when this db record was updated (useful for UI caching)
label VARCHAR(128), // display name
tagsJson VARCHAR(2048), // array of tags
icon MEDIUMBLOB,
upstreamUri VARCHAR(256) DEFAULT "",
PRIMARY KEY(id));
2023-03-16 15:37:03 +01:00
CREATE TABLE IF NOT EXISTS oidcClients(
id VARCHAR(128) NOT NULL UNIQUE,
secret VARCHAR(128) DEFAULT "",
2023-03-23 09:27:40 +01:00
appId VARCHAR(128) DEFAULT "",
name VARCHAR(128) DEFAULT "",
2023-03-17 11:29:03 +01:00
loginRedirectUri VARCHAR(256) DEFAULT "",
2023-04-04 15:38:45 +02:00
tokenSignatureAlgorithm VARCHAR(128) DEFAULT "",
2023-03-16 15:37:03 +01:00
PRIMARY KEY(id));
2024-12-07 14:35:45 +01:00
CREATE TABLE IF NOT EXISTS locks(
id VARCHAR(128) NOT NULL UNIQUE,
dataJson TEXT,
version INT DEFAULT 1
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);