123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733 |
- const { v4: uuid } = require('uuid')
- const bcrypt = require('bcryptjs-then')
- const crypto = require('crypto')
- const { DateTime } = require('luxon')
- const pem2jwk = require('pem-jwk').pem2jwk
- exports.up = async knex => {
- WIKI.logger.info('Running 3.0.0 database migration...')
- // =====================================
- // PG EXTENSIONS
- // =====================================
- await knex.raw('CREATE EXTENSION IF NOT EXISTS ltree;')
- await knex.raw('CREATE EXTENSION IF NOT EXISTS pgcrypto;')
- await knex.schema
- // =====================================
- // MODEL TABLES
- // =====================================
- // ACTIVITY LOGS -----------------------
- .createTable('activityLogs', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.timestamp('ts').notNullable().defaultTo(knex.fn.now())
- table.string('action').notNullable()
- table.jsonb('meta').notNullable()
- })
- // ANALYTICS ---------------------------
- .createTable('analytics', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('module').notNullable()
- table.boolean('isEnabled').notNullable().defaultTo(false)
- table.jsonb('config').notNullable()
- })
- // API KEYS ----------------------------
- .createTable('apiKeys', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('name').notNullable()
- table.text('key').notNullable()
- table.timestamp('expiration').notNullable().defaultTo(knex.fn.now())
- table.boolean('isRevoked').notNullable().defaultTo(false)
- table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
- table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now())
- })
- // ASSETS ------------------------------
- .createTable('assets', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('filename').notNullable()
- table.string('hash').notNullable().index()
- table.string('ext').notNullable()
- table.enum('kind', ['binary', 'image']).notNullable().defaultTo('binary')
- table.string('mime').notNullable().defaultTo('application/octet-stream')
- table.integer('fileSize').unsigned().comment('In kilobytes')
- table.jsonb('metadata')
- table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
- table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now())
- })
- // ASSET DATA --------------------------
- .createTable('assetData', table => {
- table.uuid('id').notNullable().primary()
- table.binary('data').notNullable()
- })
- // ASSET FOLDERS -----------------------
- .createTable('assetFolders', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('name').notNullable()
- table.string('slug').notNullable()
- })
- // AUTHENTICATION ----------------------
- .createTable('authentication', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('module').notNullable()
- table.boolean('isEnabled').notNullable().defaultTo(false)
- table.string('displayName').notNullable().defaultTo('')
- table.jsonb('config').notNullable().defaultTo('{}')
- table.boolean('selfRegistration').notNullable().defaultTo(false)
- table.jsonb('domainWhitelist').notNullable().defaultTo('[]')
- table.jsonb('autoEnrollGroups').notNullable().defaultTo('[]')
- })
- .createTable('commentProviders', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('module').notNullable()
- table.boolean('isEnabled').notNullable().defaultTo(false)
- table.json('config').notNullable()
- })
- // COMMENTS ----------------------------
- .createTable('comments', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.uuid('replyTo')
- table.text('content').notNullable()
- table.text('render').notNullable().defaultTo('')
- table.string('name').notNullable().defaultTo('')
- table.string('email').notNullable().defaultTo('')
- table.string('ip').notNullable().defaultTo('')
- table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
- table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now())
- })
- // GROUPS ------------------------------
- .createTable('groups', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('name').notNullable()
- table.jsonb('permissions').notNullable()
- table.jsonb('rules').notNullable()
- table.string('redirectOnLogin').notNullable().defaultTo('')
- table.string('redirectOnFirstLogin').notNullable().defaultTo('')
- table.string('redirectOnLogout').notNullable().defaultTo('')
- table.boolean('isSystem').notNullable().defaultTo(false)
- table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
- table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now())
- })
- // HOOKS -------------------------------
- .createTable('hooks', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('name').notNullable()
- table.jsonb('events').notNullable().defaultTo('[]')
- table.string('url').notNullable()
- table.boolean('includeMetadata').notNullable().defaultTo(false)
- table.boolean('includeContent').notNullable().defaultTo(false)
- table.boolean('acceptUntrusted').notNullable().defaultTo(false)
- table.string('authHeader')
- table.enum('state', ['pending', 'error', 'success']).notNullable().defaultTo('pending')
- table.string('lastErrorMessage')
- table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
- table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now())
- })
- // JOB HISTORY -------------------------
- .createTable('jobHistory', table => {
- table.uuid('id').notNullable().primary()
- table.string('task').notNullable()
- table.enum('state', ['active', 'completed', 'failed', 'interrupted']).notNullable()
- table.boolean('useWorker').notNullable().defaultTo(false)
- table.boolean('wasScheduled').notNullable().defaultTo(false)
- table.jsonb('payload')
- table.integer('attempt').notNullable().defaultTo(1)
- table.integer('maxRetries').notNullable().defaultTo(0)
- table.text('lastErrorMessage')
- table.string('executedBy')
- table.timestamp('createdAt').notNullable()
- table.timestamp('startedAt').notNullable().defaultTo(knex.fn.now())
- table.timestamp('completedAt')
- })
- // JOB SCHEDULE ------------------------
- .createTable('jobSchedule', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('task').notNullable()
- table.string('cron').notNullable()
- table.string('type').notNullable().defaultTo('system')
- table.jsonb('payload')
- table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
- table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now())
- })
- // JOB SCHEDULE ------------------------
- .createTable('jobLock', table => {
- table.string('key').notNullable().primary()
- table.string('lastCheckedBy')
- table.timestamp('lastCheckedAt').notNullable().defaultTo(knex.fn.now())
- })
- // JOBS --------------------------------
- .createTable('jobs', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('task').notNullable()
- table.boolean('useWorker').notNullable().defaultTo(false)
- table.jsonb('payload')
- table.integer('retries').notNullable().defaultTo(0)
- table.integer('maxRetries').notNullable().defaultTo(0)
- table.timestamp('waitUntil')
- table.boolean('isScheduled').notNullable().defaultTo(false)
- table.string('createdBy')
- table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
- table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now())
- })
- // LOCALES -----------------------------
- .createTable('locales', table => {
- table.string('code', 5).notNullable().primary()
- table.jsonb('strings')
- table.boolean('isRTL').notNullable().defaultTo(false)
- table.string('name').notNullable()
- table.string('nativeName').notNullable()
- table.integer('availability').notNullable().defaultTo(0)
- table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
- table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now())
- })
- // NAVIGATION ----------------------------
- .createTable('navigation', table => {
- table.string('key').notNullable().primary()
- table.jsonb('config')
- })
- // PAGE HISTORY ------------------------
- .createTable('pageHistory', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.uuid('pageId').notNullable().index()
- table.string('action').defaultTo('updated')
- table.jsonb('affectedFields').notNullable().defaultTo('[]')
- table.string('path').notNullable()
- table.string('hash').notNullable()
- table.string('alias')
- table.string('title').notNullable()
- table.string('description')
- table.string('icon')
- table.enu('publishState', ['draft', 'published', 'scheduled']).notNullable().defaultTo('draft')
- table.timestamp('publishStartDate')
- table.timestamp('publishEndDate')
- table.jsonb('config').notNullable().defaultTo('{}')
- table.jsonb('relations').notNullable().defaultTo('[]')
- table.text('content')
- table.text('render')
- table.jsonb('toc')
- table.string('editor').notNullable()
- table.string('contentType').notNullable()
- table.jsonb('scripts').notNullable().defaultTo('{}')
- table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
- table.timestamp('versionDate').notNullable().defaultTo(knex.fn.now())
- })
- // PAGE LINKS --------------------------
- .createTable('pageLinks', table => {
- table.increments('id').primary()
- table.string('path').notNullable()
- table.string('localeCode', 5).notNullable()
- })
- // PAGES -------------------------------
- .createTable('pages', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('path').notNullable()
- table.specificType('dotPath', 'ltree').notNullable().index()
- table.string('hash').notNullable()
- table.string('alias')
- table.string('title').notNullable()
- table.string('description')
- table.string('icon')
- table.enu('publishState', ['draft', 'published', 'scheduled']).notNullable().defaultTo('draft')
- table.timestamp('publishStartDate')
- table.timestamp('publishEndDate')
- table.jsonb('config').notNullable().defaultTo('{}')
- table.jsonb('relations').notNullable().defaultTo('[]')
- table.text('content')
- table.text('render')
- table.jsonb('toc')
- table.string('editor').notNullable()
- table.string('contentType').notNullable()
- table.boolean('isBrowsable').notNullable().defaultTo(true)
- table.string('password')
- table.integer('ratingScore').notNullable().defaultTo(0)
- table.integer('ratingCount').notNullable().defaultTo(0)
- table.jsonb('scripts').notNullable().defaultTo('{}')
- table.jsonb('historyData').notNullable().defaultTo('{}')
- table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
- table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now())
- })
- // RENDERERS ---------------------------
- .createTable('renderers', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('module').notNullable()
- table.boolean('isEnabled').notNullable().defaultTo(false)
- table.jsonb('config').notNullable().defaultTo('{}')
- })
- // SETTINGS ----------------------------
- .createTable('settings', table => {
- table.string('key').notNullable().primary()
- table.jsonb('value')
- })
- // SITES -------------------------------
- .createTable('sites', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('hostname').notNullable()
- table.boolean('isEnabled').notNullable().defaultTo(false)
- table.jsonb('config').notNullable()
- table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
- })
- // STORAGE -----------------------------
- .createTable('storage', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('module').notNullable()
- table.boolean('isEnabled').notNullable().defaultTo(false)
- table.jsonb('contentTypes')
- table.jsonb('assetDelivery')
- table.jsonb('versioning')
- table.jsonb('schedule')
- table.jsonb('config')
- table.jsonb('state')
- })
- // TAGS --------------------------------
- .createTable('tags', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('tag').notNullable()
- table.jsonb('display').notNullable().defaultTo('{}')
- table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
- table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now())
- })
- // USER AVATARS ------------------------
- .createTable('userAvatars', table => {
- table.uuid('id').notNullable().primary()
- table.binary('data').notNullable()
- })
- // USER KEYS ---------------------------
- .createTable('userKeys', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('kind').notNullable()
- table.string('token').notNullable()
- table.jsonb('meta').notNullable().defaultTo('{}')
- table.timestamp('validUntil').notNullable()
- table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
- })
- // USERS -------------------------------
- .createTable('users', table => {
- table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
- table.string('email').notNullable()
- table.string('name').notNullable()
- table.jsonb('auth').notNullable().defaultTo('{}')
- table.jsonb('meta').notNullable().defaultTo('{}')
- table.jsonb('prefs').notNullable().defaultTo('{}')
- table.boolean('hasAvatar').notNullable().defaultTo(false)
- table.boolean('isSystem').notNullable().defaultTo(false)
- table.boolean('isActive').notNullable().defaultTo(false)
- table.boolean('isVerified').notNullable().defaultTo(false)
- table.timestamp('lastLoginAt').index()
- table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now())
- table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now())
- })
- // =====================================
- // RELATION TABLES
- // =====================================
- // PAGE TAGS ---------------------------
- .createTable('pageTags', table => {
- table.increments('id').primary()
- table.uuid('pageId').references('id').inTable('pages').onDelete('CASCADE')
- table.uuid('tagId').references('id').inTable('tags').onDelete('CASCADE')
- })
- // USER GROUPS -------------------------
- .createTable('userGroups', table => {
- table.increments('id').primary()
- table.uuid('userId').references('id').inTable('users').onDelete('CASCADE')
- table.uuid('groupId').references('id').inTable('groups').onDelete('CASCADE')
- })
- // =====================================
- // REFERENCES
- // =====================================
- .table('activityLogs', table => {
- table.uuid('userId').notNullable().references('id').inTable('users')
- })
- .table('analytics', table => {
- table.uuid('siteId').notNullable().references('id').inTable('sites')
- })
- .table('assets', table => {
- table.uuid('folderId').notNullable().references('id').inTable('assetFolders').index()
- table.uuid('authorId').notNullable().references('id').inTable('users')
- table.uuid('siteId').notNullable().references('id').inTable('sites').index()
- })
- .table('assetFolders', table => {
- table.uuid('parentId').references('id').inTable('assetFolders').index()
- })
- .table('commentProviders', table => {
- table.uuid('siteId').notNullable().references('id').inTable('sites')
- })
- .table('comments', table => {
- table.uuid('pageId').notNullable().references('id').inTable('pages').index()
- table.uuid('authorId').notNullable().references('id').inTable('users').index()
- })
- .table('navigation', table => {
- table.uuid('siteId').notNullable().references('id').inTable('sites').index()
- })
- .table('pageHistory', table => {
- table.string('localeCode', 5).references('code').inTable('locales')
- table.uuid('authorId').notNullable().references('id').inTable('users')
- table.uuid('siteId').notNullable().references('id').inTable('sites').index()
- })
- .table('pageLinks', table => {
- table.uuid('pageId').notNullable().references('id').inTable('pages').onDelete('CASCADE')
- table.index(['path', 'localeCode'])
- })
- .table('pages', table => {
- table.string('localeCode', 5).references('code').inTable('locales').index()
- table.uuid('authorId').notNullable().references('id').inTable('users').index()
- table.uuid('creatorId').notNullable().references('id').inTable('users').index()
- table.uuid('siteId').notNullable().references('id').inTable('sites').index()
- })
- .table('storage', table => {
- table.uuid('siteId').notNullable().references('id').inTable('sites')
- })
- .table('tags', table => {
- table.uuid('siteId').notNullable().references('id').inTable('sites')
- table.unique(['siteId', 'tag'])
- })
- .table('userKeys', table => {
- table.uuid('userId').notNullable().references('id').inTable('users')
- })
- .table('users', table => {
- table.string('localeCode', 5).references('code').inTable('locales').notNullable().defaultTo('en')
- })
- // =====================================
- // DEFAULT DATA
- // =====================================
- // -> GENERATE IDS
- const groupAdminId = uuid()
- const groupGuestId = '10000000-0000-4000-8000-000000000001'
- const siteId = uuid()
- const authModuleId = uuid()
- const userAdminId = uuid()
- const userGuestId = uuid()
- // -> SYSTEM CONFIG
- WIKI.logger.info('Generating certificates...')
- const secret = crypto.randomBytes(32).toString('hex')
- const certs = crypto.generateKeyPairSync('rsa', {
- modulusLength: 2048,
- publicKeyEncoding: {
- type: 'pkcs1',
- format: 'pem'
- },
- privateKeyEncoding: {
- type: 'pkcs1',
- format: 'pem',
- cipher: 'aes-256-cbc',
- passphrase: secret
- }
- })
- await knex('settings').insert([
- {
- key: 'auth',
- value: {
- audience: 'urn:wiki.js',
- tokenExpiration: '30m',
- tokenRenewal: '14d',
- certs: {
- jwk: pem2jwk(certs.publicKey),
- public: certs.publicKey,
- private: certs.privateKey
- },
- secret,
- rootAdminUserId: userAdminId,
- guestUserId: userGuestId
- }
- },
- {
- key: 'icons',
- value: {
- fa: {
- isActive: true,
- config: {
- version: 6,
- license: 'free',
- token: ''
- }
- },
- la: {
- isActive: true
- }
- }
- },
- {
- key: 'mail',
- value: {
- senderName: '',
- senderEmail: '',
- host: '',
- port: 465,
- name: '',
- secure: true,
- verifySSL: true,
- user: '',
- pass: '',
- useDKIM: false,
- dkimDomainName: '',
- dkimKeySelector: '',
- dkimPrivateKey: ''
- }
- },
- {
- key: 'security',
- value: {
- corsConfig: '',
- corsMode: 'OFF',
- cspDirectives: '',
- disallowFloc: true,
- disallowIframe: true,
- disallowOpenRedirect: true,
- enforceCsp: false,
- enforceHsts: false,
- enforceSameOriginReferrerPolicy: true,
- forceAssetDownload: true,
- hstsDuration: 0,
- trustProxy: false,
- authJwtAudience: 'urn:wiki.js',
- authJwtExpiration: '30m',
- authJwtRenewablePeriod: '14d',
- uploadMaxFileSize: 10485760,
- uploadMaxFiles: 20,
- uploadScanSVG: true
- }
- },
- {
- key: 'update',
- value: {
- locales: true
- }
- }
- ])
- // -> DEFAULT LOCALE
- await knex('locales').insert({
- code: 'en',
- strings: {},
- isRTL: false,
- name: 'English',
- nativeName: 'English'
- })
- // -> DEFAULT SITE
- await knex('sites').insert({
- id: siteId,
- hostname: '*',
- isEnabled: true,
- config: {
- title: 'My Wiki Site',
- description: '',
- company: '',
- contentLicense: '',
- footerExtra: '',
- pageExtensions: ['md', 'html', 'txt'],
- defaults: {
- timezone: 'America/New_York',
- dateFormat: 'YYYY-MM-DD',
- timeFormat: '12h',
- tocDepth: {
- min: 1,
- max: 2
- }
- },
- features: {
- ratings: false,
- ratingsMode: 'off',
- comments: false,
- contributions: false,
- profile: true,
- search: true
- },
- logoText: true,
- sitemap: true,
- robots: {
- index: true,
- follow: true
- },
- authStrategies: [{ id: authModuleId, order: 0, isVisible: true }],
- locale: 'en',
- localeNamespacing: false,
- localeNamespaces: [],
- assets: {
- logo: false,
- logoExt: 'svg',
- favicon: false,
- faviconExt: 'svg',
- loginBg: false
- },
- theme: {
- dark: false,
- colorPrimary: '#1976D2',
- colorSecondary: '#02C39A',
- colorAccent: '#FF9800',
- colorHeader: '#000000',
- colorSidebar: '#1976D2',
- injectCSS: '',
- injectHead: '',
- injectBody: '',
- contentWidth: 'full',
- sidebarPosition: 'left',
- tocPosition: 'right',
- showSharingMenu: true,
- showPrintBtn: true,
- baseFont: 'roboto',
- contentFont: 'roboto'
- }
- }
- })
- // -> DEFAULT GROUPS
- await knex('groups').insert([
- {
- id: groupAdminId,
- name: 'Administrators',
- permissions: JSON.stringify(['manage:system']),
- rules: JSON.stringify([]),
- isSystem: true
- },
- {
- id: groupGuestId,
- name: 'Guests',
- permissions: JSON.stringify(['read:pages', 'read:assets', 'read:comments']),
- rules: JSON.stringify([
- {
- id: uuid(),
- name: 'Default Rule',
- roles: ['read:pages', 'read:assets', 'read:comments'],
- match: 'START',
- mode: 'DENY',
- path: '',
- locales: [],
- sites: []
- }
- ]),
- isSystem: true
- }
- ])
- // -> AUTHENTICATION MODULE
- await knex('authentication').insert({
- id: authModuleId,
- module: 'local',
- isEnabled: true,
- displayName: 'Local Authentication'
- })
- // -> USERS
- await knex('users').insert([
- {
- id: userAdminId,
- email: process.env.ADMIN_EMAIL ?? 'admin@example.com',
- auth: {
- [authModuleId]: {
- password: await bcrypt.hash(process.env.ADMIN_PASS || '12345678', 12),
- mustChangePwd: false, // TODO: Revert to true (below) once change password flow is implemented
- // mustChangePwd: !process.env.ADMIN_PASS,
- restrictLogin: false,
- tfaRequired: false,
- tfaSecret: ''
- }
- },
- name: 'Administrator',
- isSystem: false,
- isActive: true,
- isVerified: true,
- meta: {
- location: '',
- jobTitle: '',
- pronouns: ''
- },
- prefs: {
- timezone: 'America/New_York',
- dateFormat: 'YYYY-MM-DD',
- timeFormat: '12h',
- appearance: 'site'
- },
- localeCode: 'en'
- },
- {
- id: userGuestId,
- email: 'guest@example.com',
- auth: {},
- name: 'Guest',
- isSystem: true,
- isActive: true,
- isVerified: true,
- meta: {},
- prefs: {
- timezone: 'America/New_York',
- dateFormat: 'YYYY-MM-DD',
- timeFormat: '12h',
- appearance: 'site'
- },
- localeCode: 'en'
- }
- ])
- await knex('userGroups').insert([
- {
- userId: userAdminId,
- groupId: groupAdminId
- },
- {
- userId: userGuestId,
- groupId: groupGuestId
- }
- ])
- // -> STORAGE MODULE
- await knex('storage').insert({
- module: 'db',
- siteId,
- isEnabled: true,
- contentTypes: {
- activeTypes: ['pages', 'images', 'documents', 'others', 'large'],
- largeThreshold: '5MB'
- },
- assetDelivery: {
- streaming: true,
- directAccess: false
- },
- versioning: {
- enabled: false
- },
- state: {
- current: 'ok'
- }
- })
- // -> SCHEDULED JOBS
- await knex('jobSchedule').insert([
- {
- task: 'checkVersion',
- cron: '0 0 * * *',
- type: 'system'
- },
- {
- task: 'cleanJobHistory',
- cron: '5 0 * * *',
- type: 'system'
- },
- {
- task: 'updateLocales',
- cron: '0 0 * * *',
- type: 'system'
- }
- ])
- await knex('jobLock').insert({
- key: 'cron',
- lastCheckedBy: 'init',
- lastCheckedAt: DateTime.utc().minus({ hours: 1 }).toISO()
- })
- WIKI.logger.info('Completed 3.0.0 database migration.')
- }
- exports.down = knex => { }
|