1
0
Fork 0
mirror of synced 2024-06-14 08:24:48 +12:00

Installation identities, upgrade / downgrade events, filling in more event properties

This commit is contained in:
Rory Powell 2022-05-26 23:57:14 +01:00
parent cbc3e72757
commit 398a4e7034
35 changed files with 463 additions and 90 deletions

View file

@ -31,6 +31,7 @@ exports.StaticDatabases = {
name: "global-info",
docs: {
tenants: "tenants",
install: "install",
},
},
}

View file

@ -14,15 +14,21 @@ import {
SettingsConfig,
CloudAccount,
UserIdentity,
InstallationIdentity,
Installation,
isInstallation,
} from "@budibase/types"
import { analyticsProcessor } from "./processors"
import { processors } from "./processors"
import * as dbUtils from "../db/utils"
import { Configs } from "../constants"
import * as hashing from "../hashing"
const pkg = require("../../package.json")
export const getCurrentIdentity = async (): Promise<Identity> => {
const user: SessionUser | undefined = context.getUser()
let tenantId = context.getTenantId()
const tenantId = await getGlobalTenantId(context.getTenantId())
let id: string
let type: IdentityType
@ -30,12 +36,14 @@ export const getCurrentIdentity = async (): Promise<Identity> => {
id = user._id
type = IdentityType.USER
} else {
const global = await getGlobalIdentifiers(tenantId)
id = global.id
tenantId = global.tenantId
id = tenantId
type = IdentityType.TENANT
}
if (user && isInstallation(user)) {
type = IdentityType.INSTALLATION
}
return {
id,
tenantId,
@ -43,36 +51,29 @@ export const getCurrentIdentity = async (): Promise<Identity> => {
}
}
const getGlobalId = async (): Promise<string> => {
const getGlobalId = async (tenantId: string): Promise<string> => {
const db = context.getGlobalDB()
const config: SettingsConfig = await dbUtils.getScopedFullConfig(db, {
type: Configs.SETTINGS,
})
let globalId: string
if (config.config.globalId) {
return config.config.globalId
} else {
const globalId = `global_${hashing.newid()}`
globalId = `${hashing.newid()}_${tenantId}`
config.config.globalId = globalId
await db.put(config)
return globalId
}
}
const getGlobalIdentifiers = async (
tenantId: string
): Promise<{ id: string; tenantId: string }> => {
const getGlobalTenantId = async (tenantId: string): Promise<string> => {
if (env.SELF_HOSTED) {
const globalId = await getGlobalId()
return {
id: globalId,
tenantId: `${globalId}-${tenantId}`,
}
return getGlobalId(tenantId)
} else {
// tenant id's in the cloud are already unique
return {
id: tenantId,
tenantId: tenantId,
}
return tenantId
}
}
@ -80,13 +81,34 @@ const getHostingFromEnv = () => {
return env.SELF_HOSTED ? Hosting.SELF : Hosting.CLOUD
}
export const identifyInstallation = async (
install: Installation,
timestamp: string | number
) => {
const id = install.installId
// the default tenant id, so we can match installations to other events
const tenantId = await getGlobalTenantId(context.getTenantId())
const version: string = pkg.version as string
const type = IdentityType.INSTALLATION
const hosting = getHostingFromEnv()
const identity: InstallationIdentity = {
id,
tenantId,
type,
version,
hosting,
}
await identify(identity, timestamp)
}
export const identifyTenant = async (
tenantId: string,
account: CloudAccount | undefined,
timestamp?: string | number
) => {
const global = await getGlobalIdentifiers(tenantId)
const id = global.id
const globalTenantId = await getGlobalTenantId(tenantId)
const id = globalTenantId
const hosting = getHostingFromEnv()
const type = IdentityType.TENANT
const profession = account?.profession
@ -94,7 +116,7 @@ export const identifyTenant = async (
const identity: TenantIdentity = {
id,
tenantId: global.tenantId,
tenantId: globalTenantId,
hosting,
type,
profession,
@ -116,7 +138,8 @@ export const identifyUser = async (
let admin = user.admin?.global
let providerType = user.providerType
const accountHolder = account?.budibaseUserId === user._id
const verified = account ? account.verified : false
const verified =
account && account?.budibaseUserId === user._id ? account.verified : false
const profession = account?.profession
const companySize = account?.size
@ -170,6 +193,9 @@ export const identifyAccount = async (account: Account) => {
await identify(identity)
}
const identify = async (identity: Identity, timestamp?: string | number) => {
await analyticsProcessor.identify(identity, timestamp)
export const identify = async (
identity: Identity,
timestamp?: string | number
) => {
await processors.identify(identity, timestamp)
}

View file

@ -22,6 +22,21 @@ export default class LoggingProcessor implements EventProcessor {
)
}
async identify(identity: Identity, timestamp?: string | number) {
if (env.SELF_HOSTED && !env.isDev()) {
return
}
let timestampString = ""
if (timestamp) {
timestampString = `[timestamp=${new Date(timestamp).toISOString()}]`
}
console.log(
`[audit] [${JSON.stringify(identity)}] ${timestampString} identified`
)
}
shutdown(): void {
// no-op
}

View file

@ -20,6 +20,15 @@ export default class Processor implements EventProcessor {
}
}
async identify(
identity: Identity,
timestamp?: string | number
): Promise<void> {
for (const eventProcessor of this.processors) {
await eventProcessor.identify(identity, timestamp)
}
}
shutdown() {
for (const eventProcessor of this.processors) {
eventProcessor.shutdown()

View file

@ -12,5 +12,6 @@ export interface EventProcessor {
properties: any,
timestamp?: string | number
): Promise<void>
identify(identity: Identity, timestamp?: string | number): Promise<void>
shutdown(): void
}

View file

@ -10,16 +10,22 @@ import {
SSOType,
SSOUpdatedEvent,
} from "@budibase/types"
import { identification } from ".."
export async function login(source: LoginSource) {
const identity = await identification.getCurrentIdentity()
const properties: LoginEvent = {
userId: identity.id,
source,
}
await publishEvent(Event.AUTH_LOGIN, properties)
}
export async function logout() {
const properties: LogoutEvent = {}
const identity = await identification.getCurrentIdentity()
const properties: LogoutEvent = {
userId: identity.id,
}
await publishEvent(Event.AUTH_LOGOUT, properties)
}

View file

@ -3,7 +3,6 @@ import {
Automation,
Event,
AutomationStep,
AutomationTrigger,
AutomationCreatedEvent,
AutomationDeletedEvent,
AutomationTestedEvent,
@ -13,17 +12,42 @@ import {
} from "@budibase/types"
export async function created(automation: Automation, timestamp?: string) {
const properties: AutomationCreatedEvent = {}
const properties: AutomationCreatedEvent = {
appId: automation.appId,
automationId: automation._id as string,
triggerId: automation.definition?.trigger?.id,
triggerType: automation.definition?.trigger?.stepId,
}
await publishEvent(Event.AUTOMATION_CREATED, properties, timestamp)
}
export async function triggerUpdated(automation: Automation) {
const properties: AutomationTriggerUpdatedEvent = {
appId: automation.appId,
automationId: automation._id as string,
triggerId: automation.definition?.trigger?.id,
triggerType: automation.definition?.trigger?.stepId,
}
await publishEvent(Event.AUTOMATION_TRIGGER_UPDATED, properties)
}
export async function deleted(automation: Automation) {
const properties: AutomationDeletedEvent = {}
const properties: AutomationDeletedEvent = {
appId: automation.appId,
automationId: automation._id as string,
triggerId: automation.definition?.trigger?.id,
triggerType: automation.definition?.trigger?.stepId,
}
await publishEvent(Event.AUTOMATION_DELETED, properties)
}
export async function tested(automation: Automation) {
const properties: AutomationTestedEvent = {}
const properties: AutomationTestedEvent = {
appId: automation.appId,
automationId: automation._id as string,
triggerId: automation.definition?.trigger?.id,
triggerType: automation.definition?.trigger?.stepId,
}
await publishEvent(Event.AUTOMATION_TESTED, properties)
}
@ -32,7 +56,14 @@ export async function stepCreated(
step: AutomationStep,
timestamp?: string
) {
const properties: AutomationStepCreatedEvent = {}
const properties: AutomationStepCreatedEvent = {
appId: automation.appId,
automationId: automation._id as string,
triggerId: automation.definition?.trigger?.id,
triggerType: automation.definition?.trigger?.stepId,
stepId: step.id,
stepType: step.stepId,
}
await publishEvent(Event.AUTOMATION_STEP_CREATED, properties, timestamp)
}
@ -40,14 +71,13 @@ export async function stepDeleted(
automation: Automation,
step: AutomationStep
) {
const properties: AutomationStepDeletedEvent = {}
const properties: AutomationStepDeletedEvent = {
appId: automation.appId,
automationId: automation._id as string,
triggerId: automation.definition?.trigger?.id,
triggerType: automation.definition?.trigger?.stepId,
stepId: step.id,
stepType: step.stepId,
}
await publishEvent(Event.AUTOMATION_STEP_DELETED, properties)
}
export async function triggerUpdated(
automation: Automation,
trigger: AutomationTrigger
) {
const properties: AutomationTriggerUpdatedEvent = {}
await publishEvent(Event.AUTOMATION_TRIGGER_UPDATED, properties)
}

View file

@ -8,16 +8,25 @@ import {
} from "@budibase/types"
export async function created(datasource: Datasource, timestamp?: string) {
const properties: DatasourceCreatedEvent = {}
const properties: DatasourceCreatedEvent = {
datasourceId: datasource._id as string,
source: datasource.source,
}
await publishEvent(Event.DATASOURCE_CREATED, properties, timestamp)
}
export async function updated(datasource: Datasource) {
const properties: DatasourceUpdatedEvent = {}
const properties: DatasourceUpdatedEvent = {
datasourceId: datasource._id as string,
source: datasource.source,
}
await publishEvent(Event.DATASOURCE_UPDATED, properties)
}
export async function deleted(datasource: Datasource) {
const properties: DatasourceDeletedEvent = {}
const properties: DatasourceDeletedEvent = {
datasourceId: datasource._id as string,
source: datasource.source,
}
await publishEvent(Event.DATASOURCE_DELETED, properties)
}

View file

@ -15,3 +15,4 @@ export * as table from "./table"
export * as serve from "./serve"
export * as user from "./user"
export * as view from "./view"
export * as version from "./version"

View file

@ -7,11 +7,15 @@ import {
} from "@budibase/types"
export async function created(layout: Layout, timestamp?: string) {
const properties: LayoutCreatedEvent = {}
const properties: LayoutCreatedEvent = {
layoutId: layout._id as string,
}
await publishEvent(Event.LAYOUT_CREATED, properties, timestamp)
}
export async function deleted(layout: Layout) {
const properties: LayoutDeletedEvent = {}
const properties: LayoutDeletedEvent = {
layoutId: layout._id as string,
}
await publishEvent(Event.LAYOUT_DELETED, properties)
}

View file

@ -1,5 +1,5 @@
import { publishEvent } from "../events"
import { Event, VersionCheckedEvent } from "@budibase/types"
import { Event } from "@budibase/types"
export async function nameUpdated(timestamp?: string | number) {
const properties = {}
@ -16,14 +16,8 @@ export async function platformURLUpdated(timestamp?: string | number) {
await publishEvent(Event.ORG_PLATFORM_URL_UPDATED, properties, timestamp)
}
export async function versionChecked(version: number) {
const properties: VersionCheckedEvent = {
version,
}
await publishEvent(Event.UPDATE_VERSION_CHECKED, properties)
}
// TODO
export async function analyticsOptOut() {
const properties = {}
await publishEvent(Event.ANALYTICS_OPT_OUT, properties)

View file

@ -0,0 +1,26 @@
import { publishEvent } from "../events"
import { Event, VersionCheckedEvent, VersionChangeEvent } from "@budibase/types"
export async function checked(version: string) {
const properties: VersionCheckedEvent = {
currentVersion: version,
}
await publishEvent(Event.VERSION_CHECKED, properties)
}
export async function upgraded(from: string, to: string) {
const properties: VersionChangeEvent = {
from,
to,
}
await publishEvent(Event.VERSION_UPGRADED, properties)
}
export async function downgraded(from: string, to: string) {
const properties: VersionChangeEvent = {
from,
to,
}
await publishEvent(Event.VERSION_DOWNGRADED, properties)
}

View file

@ -1,6 +1,6 @@
const { DEFAULT_TENANT_ID } = require("../constants")
const { doWithDB } = require("../db")
const { DocumentTypes } = require("../db/constants")
const { DocumentTypes, StaticDatabases } = require("../db/constants")
const { getAllApps } = require("../db/utils")
const environment = require("../environment")
const {
@ -11,8 +11,9 @@ const {
} = require("../tenancy")
exports.MIGRATION_TYPES = {
GLOBAL: "global", // run once, recorded in global db, global db is provided as an argument
GLOBAL: "global", // run once per tenant, recorded in global db, global db is provided as an argument
APP: "app", // run per app, recorded in each app db, app db is provided as an argument
INSTALLATION: "installation", // run once, recorded in global info db, global info db is provided as an argument
}
exports.getMigrationsDoc = async db => {
@ -22,14 +23,19 @@ exports.getMigrationsDoc = async db => {
} catch (err) {
if (err.status && err.status === 404) {
return { _id: DocumentTypes.MIGRATIONS }
} else {
console.error(err)
throw err
}
console.error(err)
}
}
exports.runMigration = async (migration, options = {}) => {
const tenantId = getTenantId()
const migrationType = migration.type
let tenantId
if (migrationType !== exports.MIGRATION_TYPES.INSTALLATION) {
tenantId = getTenantId()
}
const migrationName = migration.name
const silent = migration.silent
@ -46,10 +52,10 @@ exports.runMigration = async (migration, options = {}) => {
} else if (migrationType === exports.MIGRATION_TYPES.APP) {
const apps = await getAllApps(migration.opts)
dbNames = apps.map(app => app.appId)
} else if (migrationType === exports.MIGRATION_TYPES.INSTALLATION) {
dbNames = [StaticDatabases.PLATFORM_INFO.name]
} else {
throw new Error(
`[Tenant: ${tenantId}] Unrecognised migration type [${migrationType}]`
)
throw new Error(`Unrecognised migration type [${migrationType}]`)
}
const length = dbNames.length

View file

@ -129,6 +129,7 @@
"pouchdb-find": "^7.2.2",
"pouchdb-replication-stream": "1.2.9",
"redis": "4",
"semver": "^7.0.0",
"server-destroy": "1.0.1",
"svelte": "^3.38.2",
"swagger-parser": "^10.0.3",
@ -159,6 +160,7 @@
"@types/node": "^15.12.4",
"@types/oracledb": "^5.2.1",
"@types/redis": "^4.0.11",
"@types/semver": "^7.0.0",
"@typescript-eslint/parser": "5.12.0",
"apidoc": "^0.50.2",
"babel-jest": "^27.0.2",

View file

@ -131,5 +131,5 @@ exports.getBudibaseVersion = async ctx => {
ctx.body = {
version,
}
await events.org.versionChecked(version)
await events.version.versionChecked(version)
}

View file

@ -17,6 +17,7 @@ const bullboard = require("./automations/bullboard")
import redis from "./utilities/redis"
import * as migrations from "./migrations"
import { events } from "@budibase/backend-core"
import * as installation from "./installation"
const app = new Koa()
@ -108,3 +109,6 @@ if (!env.HTTP_MIGRATIONS && !env.isTest()) {
shutdown()
})
}
// check for version updates
installation.checkInstallVersion()

View file

@ -0,0 +1,92 @@
import {
db as dbUtils,
events,
utils,
context,
tenancy,
} from "@budibase/backend-core"
import { Installation } from "@budibase/types"
import semver from "semver"
const pkg = require("../package.json")
export const getInstall = async (): Promise<Installation> => {
return dbUtils.doWithDB(
dbUtils.StaticDatabases.PLATFORM_INFO.name,
async (platformDb: any) => {
let install: Installation
try {
install = await platformDb.get(
dbUtils.StaticDatabases.PLATFORM_INFO.docs.install
)
} catch (e: any) {
if (e.status === 404) {
install = {
_id: dbUtils.StaticDatabases.PLATFORM_INFO.docs.install,
installId: utils.newid(),
version: pkg.version,
}
const resp = await platformDb.put(install)
install._rev = resp.rev
} else {
throw e
}
}
return install
},
{}
)
}
const updateVersion = async (version: string): Promise<boolean> => {
try {
await dbUtils.doWithDB(
dbUtils.StaticDatabases.PLATFORM_INFO.name,
async (platformDb: any) => {
const install = await getInstall()
install.version = version
await platformDb.put(install)
},
{}
)
} catch (e: any) {
if (e.status === 409) {
// do nothing - version has already been updated
// likely in clustered environment
return false
}
throw e
}
return true
}
export const checkInstallVersion = async (): Promise<void> => {
const install = await getInstall()
const currentVersion = install.version
const newVersion = pkg.version
if (currentVersion !== newVersion) {
const isUpgrade = semver.gt(newVersion, currentVersion)
const isDowngrade = semver.lt(newVersion, currentVersion)
const success = await updateVersion(newVersion)
if (success) {
await context.doInUserContext(
{
_id: install.installId,
isInstall: true,
tenantId: tenancy.DEFAULT_TENANT_ID,
},
async () => {
if (isUpgrade) {
await events.version.upgraded(currentVersion, newVersion)
} else if (isDowngrade) {
await events.version.downgraded(currentVersion, newVersion)
}
}
)
}
}
}

View file

@ -2,8 +2,9 @@ import * as users from "./global/users"
import * as rows from "./global/rows"
import * as configs from "./global/configs"
import { tenancy, events, migrations, accounts } from "@budibase/backend-core"
import { CloudAccount } from "@budibase/types"
import { CloudAccount, Installation } from "@budibase/types"
import env from "../../../environment"
import * as installation from "../../../installation"
/**
* Date:
@ -39,10 +40,12 @@ export const isComplete = async (): Promise<boolean> => {
return !!migrationsDoc.event_global_backfill
}
const getInstallTimestamp = async (db: any): Promise<number | undefined> => {
const allUsers = await users.getUsers(db)
export const getInstallTimestamp = async (
globalDb: any
): Promise<number | undefined> => {
const allUsers = await users.getUsers(globalDb)
// get the olders user timestamp
// get the oldest user timestamp
const timestamps = allUsers
.map(user => user.createdAt)
.filter(timestamp => !!timestamp)

View file

@ -1,2 +1,3 @@
export * as app from "./app"
export * as global from "./global"
export * as installation from "./installation"

View file

@ -0,0 +1,22 @@
import { events, tenancy } from "@budibase/backend-core"
import { Installation } from "@budibase/types"
import * as installation from "../../../installation"
import * as global from "./global"
/**
* Date:
* May 2022
*
* Description:
* Backfill installation events.
*/
export const run = async () => {
// need to use the default tenant to try to get the installation time
await tenancy.doInTenant(tenancy.DEFAULT_TENANT_ID, async () => {
const db = tenancy.getGlobalDB()
const installTimestamp = (await global.getInstallTimestamp(db)) as number
const install: Installation = await installation.getInstall()
await events.identification.identifyInstallation(install, installTimestamp)
})
}

View file

@ -73,6 +73,12 @@ export const MIGRATIONS: Migration[] = [
fn: backfill.global.run,
silent: !!env.SELF_HOSTED, // reduce noisy logging
},
{
type: migrations.MIGRATION_TYPES.INSTALLATION,
name: "event_installation_backfill",
fn: backfill.installation.run,
silent: !!env.SELF_HOSTED, // reduce noisy logging
},
]
export const migrate = async (options?: MigrationOptions) => {

View file

@ -2754,6 +2754,11 @@
"@types/tough-cookie" "*"
form-data "^2.5.0"
"@types/semver@^7.0.0":
version "7.3.9"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc"
integrity sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==
"@types/serve-static@*":
version "1.13.10"
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9"
@ -11645,6 +11650,13 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
semver@^7.0.0:
version "7.3.7"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
dependencies:
lru-cache "^6.0.0"
seq-queue@^0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/seq-queue/-/seq-queue-0.0.5.tgz#d56812e1c017a6e4e7c3e3a37a1da6d78dd3c93e"

View file

@ -33,4 +33,17 @@ export const isUserSession = (
return !user.account || user.account?.hosting === Hosting.CLOUD
}
export type SessionUser = AccountUserSession | BudibaseUserSession
// not technically a session, but used to identify the installation
export interface InstallationSession {
_id: string
isInstallation: boolean
}
export const isInstallation = (user: any): user is InstallationSession => {
return !!user.isInstallation
}
export type SessionUser =
| AccountUserSession
| BudibaseUserSession
| InstallationSession

View file

@ -5,8 +5,15 @@ export interface Automation extends Document {
steps: AutomationStep[]
trigger: AutomationTrigger
}
appId: string
}
export interface AutomationStep {}
export interface AutomationStep {
id: string
stepId: string
}
export interface AutomationTrigger {}
export interface AutomationTrigger {
id: string
stepId: string
}

View file

@ -1,3 +1,5 @@
import { Document } from "../document"
export interface Datasource extends Document {}
export interface Datasource extends Document {
source: string
}

View file

@ -1 +1,9 @@
import { Document } from "../document"
export interface GlobalInfo {}
export interface Installation extends Document {
_id: string
installId: string
version: string
}

View file

@ -2,15 +2,26 @@ export type LoginSource = "local" | "google" | "oidc"
export type SSOType = "oidc" | "google"
export interface LoginEvent {
userId: string
source: LoginSource
}
export interface LogoutEvent {}
export interface LogoutEvent {
userId: string
}
export interface SSOCreatedEvent {}
export interface SSOCreatedEvent {
type: SSOType
}
export interface SSOUpdatedEvent {}
export interface SSOUpdatedEvent {
type: SSOType
}
export interface SSOActivatedEvent {}
export interface SSOActivatedEvent {
type: SSOType
}
export interface SSODeactivatedEvent {}
export interface SSODeactivatedEvent {
type: SSOType
}

View file

@ -1,11 +1,45 @@
export interface AutomationCreatedEvent {}
export interface AutomationCreatedEvent {
appId: string
automationId: string
triggerId: string
triggerType: string
}
export interface AutomationDeletedEvent {}
export interface AutomationTriggerUpdatedEvent {
appId: string
automationId: string
triggerId: string
triggerType: string
}
export interface AutomationTestedEvent {}
export interface AutomationDeletedEvent {
appId: string
automationId: string
triggerId: string
triggerType: string
}
export interface AutomationStepCreatedEvent {}
export interface AutomationTestedEvent {
appId: string
automationId: string
triggerId: string
triggerType: string
}
export interface AutomationStepDeletedEvent {}
export interface AutomationStepCreatedEvent {
appId: string
automationId: string
triggerId: string
triggerType: string
stepId: string
stepType: string
}
export interface AutomationTriggerUpdatedEvent {}
export interface AutomationStepDeletedEvent {
appId: string
automationId: string
triggerId: string
triggerType: string
stepId: string
stepType: string
}

View file

@ -1,5 +1,14 @@
export interface DatasourceCreatedEvent {}
export interface DatasourceCreatedEvent {
datasourceId: string
source: string
}
export interface DatasourceUpdatedEvent {}
export interface DatasourceUpdatedEvent {
datasourceId: string
source: string
}
export interface DatasourceDeletedEvent {}
export interface DatasourceDeletedEvent {
datasourceId: string
source: string
}

View file

@ -38,7 +38,9 @@ export enum Event {
ORG_PLATFORM_URL_UPDATED = "org:platformurl:updated",
// ORG / UPDATE
UPDATE_VERSION_CHECKED = "version:checked",
VERSION_CHECKED = "version:checked",
VERSION_UPGRADED = "version:upgraded",
VERSION_DOWNGRADED = "version:downgraded",
// ORG / ANALYTICS
ANALYTICS_OPT_OUT = "analytics:opt:out",

View file

@ -1,8 +1,9 @@
import { Hosting } from "../core"
export enum IdentityType {
USER = "user", // cloud and self hosted users
TENANT = "tenant", // cloud and self hosted tenants
USER = "user",
TENANT = "tenant",
INSTALLATION = "installation",
}
export interface Identity {
@ -11,6 +12,11 @@ export interface Identity {
type: IdentityType
}
export interface InstallationIdentity extends Identity {
version: string
hosting: Hosting
}
export interface TenantIdentity extends Identity {
hosting: Hosting
profession?: string

View file

@ -6,7 +6,7 @@ export * from "./datasource"
export * from "./event"
export * from "./layout"
export * from "./license"
export * from "./org"
export * from "./version"
export * from "./query"
export * from "./role"
export * from "./rows"

View file

@ -1,3 +1,7 @@
export interface LayoutCreatedEvent {}
export interface LayoutCreatedEvent {
layoutId: string
}
export interface LayoutDeletedEvent {}
export interface LayoutDeletedEvent {
layoutId: string
}

View file

@ -1 +0,0 @@
export interface VersionCheckedEvent {}

View file

@ -0,0 +1,8 @@
export interface VersionCheckedEvent {
currentVersion: string
}
export interface VersionChangeEvent {
from: string
to: string
}