2023-06-01 12:32:51 +02:00
|
|
|
import { RegisterQueueOptions } from '@nestjs/bullmq';
|
2024-03-20 21:04:03 +01:00
|
|
|
import { ConfigModuleOptions } from '@nestjs/config';
|
2024-05-14 20:43:49 +02:00
|
|
|
import { CronExpression } from '@nestjs/schedule';
|
2023-06-01 12:32:51 +02:00
|
|
|
import { QueueOptions } from 'bullmq';
|
2024-04-16 01:39:06 +02:00
|
|
|
import { Request, Response } from 'express';
|
2023-03-31 16:36:08 +02:00
|
|
|
import { RedisOptions } from 'ioredis';
|
2024-07-26 16:23:58 +02:00
|
|
|
import Joi, { Root } from 'joi';
|
2024-04-16 01:39:06 +02:00
|
|
|
import { CLS_ID, ClsModuleOptions } from 'nestjs-cls';
|
2024-06-05 23:07:47 +02:00
|
|
|
import { ImmichHeader } from 'src/dtos/auth.dto';
|
2024-09-27 16:28:42 +02:00
|
|
|
import {
|
|
|
|
AudioCodec,
|
|
|
|
Colorspace,
|
|
|
|
CQMode,
|
|
|
|
ImageFormat,
|
|
|
|
LogLevel,
|
|
|
|
ToneMapping,
|
|
|
|
TranscodeHWAccel,
|
|
|
|
TranscodePolicy,
|
|
|
|
VideoCodec,
|
|
|
|
VideoContainer,
|
|
|
|
} from 'src/enum';
|
2024-05-14 20:43:49 +02:00
|
|
|
import { ConcurrentQueueName, QueueName } from 'src/interfaces/job.interface';
|
2024-09-28 08:01:04 +02:00
|
|
|
import { ImageOutputConfig } from 'src/interfaces/media.interface';
|
2024-05-14 20:43:49 +02:00
|
|
|
|
|
|
|
export interface SystemConfig {
|
|
|
|
ffmpeg: {
|
|
|
|
crf: number;
|
|
|
|
threads: number;
|
|
|
|
preset: string;
|
|
|
|
targetVideoCodec: VideoCodec;
|
|
|
|
acceptedVideoCodecs: VideoCodec[];
|
|
|
|
targetAudioCodec: AudioCodec;
|
|
|
|
acceptedAudioCodecs: AudioCodec[];
|
2024-07-21 23:14:23 +02:00
|
|
|
acceptedContainers: VideoContainer[];
|
2024-05-14 20:43:49 +02:00
|
|
|
targetResolution: string;
|
|
|
|
maxBitrate: string;
|
|
|
|
bframes: number;
|
|
|
|
refs: number;
|
|
|
|
gopSize: number;
|
|
|
|
npl: number;
|
|
|
|
temporalAQ: boolean;
|
|
|
|
cqMode: CQMode;
|
|
|
|
twoPass: boolean;
|
|
|
|
preferredHwDevice: string;
|
|
|
|
transcode: TranscodePolicy;
|
|
|
|
accel: TranscodeHWAccel;
|
2024-05-16 19:30:26 +02:00
|
|
|
accelDecode: boolean;
|
2024-05-14 20:43:49 +02:00
|
|
|
tonemap: ToneMapping;
|
|
|
|
};
|
|
|
|
job: Record<ConcurrentQueueName, { concurrency: number }>;
|
|
|
|
logging: {
|
|
|
|
enabled: boolean;
|
|
|
|
level: LogLevel;
|
|
|
|
};
|
|
|
|
machineLearning: {
|
|
|
|
enabled: boolean;
|
|
|
|
url: string;
|
|
|
|
clip: {
|
|
|
|
enabled: boolean;
|
|
|
|
modelName: string;
|
|
|
|
};
|
2024-05-16 19:08:37 +02:00
|
|
|
duplicateDetection: {
|
|
|
|
enabled: boolean;
|
|
|
|
maxDistance: number;
|
|
|
|
};
|
2024-05-14 20:43:49 +02:00
|
|
|
facialRecognition: {
|
|
|
|
enabled: boolean;
|
|
|
|
modelName: string;
|
|
|
|
minScore: number;
|
|
|
|
minFaces: number;
|
|
|
|
maxDistance: number;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
map: {
|
|
|
|
enabled: boolean;
|
|
|
|
lightStyle: string;
|
|
|
|
darkStyle: string;
|
|
|
|
};
|
|
|
|
reverseGeocoding: {
|
|
|
|
enabled: boolean;
|
|
|
|
};
|
2024-09-05 00:23:58 +02:00
|
|
|
metadata: {
|
|
|
|
faces: {
|
|
|
|
import: boolean;
|
|
|
|
};
|
|
|
|
};
|
2024-05-14 20:43:49 +02:00
|
|
|
oauth: {
|
|
|
|
autoLaunch: boolean;
|
|
|
|
autoRegister: boolean;
|
|
|
|
buttonText: string;
|
|
|
|
clientId: string;
|
|
|
|
clientSecret: string;
|
|
|
|
defaultStorageQuota: number;
|
|
|
|
enabled: boolean;
|
|
|
|
issuerUrl: string;
|
|
|
|
mobileOverrideEnabled: boolean;
|
|
|
|
mobileRedirectUri: string;
|
|
|
|
scope: string;
|
|
|
|
signingAlgorithm: string;
|
2024-07-11 13:55:00 +02:00
|
|
|
profileSigningAlgorithm: string;
|
2024-05-14 20:43:49 +02:00
|
|
|
storageLabelClaim: string;
|
|
|
|
storageQuotaClaim: string;
|
|
|
|
};
|
|
|
|
passwordLogin: {
|
|
|
|
enabled: boolean;
|
|
|
|
};
|
|
|
|
storageTemplate: {
|
|
|
|
enabled: boolean;
|
|
|
|
hashVerificationEnabled: boolean;
|
|
|
|
template: string;
|
|
|
|
};
|
|
|
|
image: {
|
2024-09-28 08:01:04 +02:00
|
|
|
thumbnail: ImageOutputConfig;
|
|
|
|
preview: ImageOutputConfig;
|
2024-05-14 20:43:49 +02:00
|
|
|
colorspace: Colorspace;
|
|
|
|
extractEmbedded: boolean;
|
|
|
|
};
|
|
|
|
newVersionCheck: {
|
|
|
|
enabled: boolean;
|
|
|
|
};
|
|
|
|
trash: {
|
|
|
|
enabled: boolean;
|
|
|
|
days: number;
|
|
|
|
};
|
|
|
|
theme: {
|
|
|
|
customCss: string;
|
|
|
|
};
|
|
|
|
library: {
|
|
|
|
scan: {
|
|
|
|
enabled: boolean;
|
|
|
|
cronExpression: string;
|
|
|
|
};
|
|
|
|
watch: {
|
|
|
|
enabled: boolean;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
notifications: {
|
|
|
|
smtp: {
|
|
|
|
enabled: boolean;
|
|
|
|
from: string;
|
|
|
|
replyTo: string;
|
|
|
|
transport: {
|
|
|
|
ignoreCert: boolean;
|
|
|
|
host: string;
|
|
|
|
port: number;
|
|
|
|
username: string;
|
|
|
|
password: string;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
server: {
|
|
|
|
externalDomain: string;
|
|
|
|
loginPageMessage: string;
|
|
|
|
};
|
|
|
|
user: {
|
|
|
|
deleteDelay: number;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export const defaults = Object.freeze<SystemConfig>({
|
|
|
|
ffmpeg: {
|
|
|
|
crf: 23,
|
|
|
|
threads: 0,
|
|
|
|
preset: 'ultrafast',
|
|
|
|
targetVideoCodec: VideoCodec.H264,
|
|
|
|
acceptedVideoCodecs: [VideoCodec.H264],
|
|
|
|
targetAudioCodec: AudioCodec.AAC,
|
|
|
|
acceptedAudioCodecs: [AudioCodec.AAC, AudioCodec.MP3, AudioCodec.LIBOPUS],
|
2024-07-21 23:14:23 +02:00
|
|
|
acceptedContainers: [VideoContainer.MOV, VideoContainer.OGG, VideoContainer.WEBM],
|
2024-05-14 20:43:49 +02:00
|
|
|
targetResolution: '720',
|
|
|
|
maxBitrate: '0',
|
|
|
|
bframes: -1,
|
|
|
|
refs: 0,
|
|
|
|
gopSize: 0,
|
|
|
|
npl: 0,
|
|
|
|
temporalAQ: false,
|
|
|
|
cqMode: CQMode.AUTO,
|
|
|
|
twoPass: false,
|
|
|
|
preferredHwDevice: 'auto',
|
|
|
|
transcode: TranscodePolicy.REQUIRED,
|
|
|
|
tonemap: ToneMapping.HABLE,
|
|
|
|
accel: TranscodeHWAccel.DISABLED,
|
2024-05-16 19:30:26 +02:00
|
|
|
accelDecode: false,
|
2024-05-14 20:43:49 +02:00
|
|
|
},
|
|
|
|
job: {
|
|
|
|
[QueueName.BACKGROUND_TASK]: { concurrency: 5 },
|
|
|
|
[QueueName.SMART_SEARCH]: { concurrency: 2 },
|
|
|
|
[QueueName.METADATA_EXTRACTION]: { concurrency: 5 },
|
|
|
|
[QueueName.FACE_DETECTION]: { concurrency: 2 },
|
|
|
|
[QueueName.SEARCH]: { concurrency: 5 },
|
|
|
|
[QueueName.SIDECAR]: { concurrency: 5 },
|
|
|
|
[QueueName.LIBRARY]: { concurrency: 5 },
|
|
|
|
[QueueName.MIGRATION]: { concurrency: 5 },
|
2024-06-05 12:45:53 +02:00
|
|
|
[QueueName.THUMBNAIL_GENERATION]: { concurrency: 3 },
|
2024-05-14 20:43:49 +02:00
|
|
|
[QueueName.VIDEO_CONVERSION]: { concurrency: 1 },
|
|
|
|
[QueueName.NOTIFICATION]: { concurrency: 5 },
|
|
|
|
},
|
|
|
|
logging: {
|
|
|
|
enabled: true,
|
|
|
|
level: LogLevel.LOG,
|
|
|
|
},
|
|
|
|
machineLearning: {
|
|
|
|
enabled: process.env.IMMICH_MACHINE_LEARNING_ENABLED !== 'false',
|
|
|
|
url: process.env.IMMICH_MACHINE_LEARNING_URL || 'http://immich-machine-learning:3003',
|
|
|
|
clip: {
|
|
|
|
enabled: true,
|
|
|
|
modelName: 'ViT-B-32__openai',
|
|
|
|
},
|
2024-05-16 19:08:37 +02:00
|
|
|
duplicateDetection: {
|
2024-05-27 02:51:41 +02:00
|
|
|
enabled: true,
|
2024-06-30 17:36:02 +02:00
|
|
|
maxDistance: 0.01,
|
2024-05-16 19:08:37 +02:00
|
|
|
},
|
2024-05-14 20:43:49 +02:00
|
|
|
facialRecognition: {
|
|
|
|
enabled: true,
|
|
|
|
modelName: 'buffalo_l',
|
|
|
|
minScore: 0.7,
|
|
|
|
maxDistance: 0.5,
|
|
|
|
minFaces: 3,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
map: {
|
|
|
|
enabled: true,
|
2024-09-23 22:30:23 +02:00
|
|
|
lightStyle: 'https://tiles.immich.cloud/v1/style/light.json',
|
|
|
|
darkStyle: 'https://tiles.immich.cloud/v1/style/dark.json',
|
2024-05-14 20:43:49 +02:00
|
|
|
},
|
|
|
|
reverseGeocoding: {
|
|
|
|
enabled: true,
|
|
|
|
},
|
2024-09-05 00:23:58 +02:00
|
|
|
metadata: {
|
|
|
|
faces: {
|
|
|
|
import: false,
|
|
|
|
},
|
|
|
|
},
|
2024-05-14 20:43:49 +02:00
|
|
|
oauth: {
|
|
|
|
autoLaunch: false,
|
|
|
|
autoRegister: true,
|
|
|
|
buttonText: 'Login with OAuth',
|
|
|
|
clientId: '',
|
|
|
|
clientSecret: '',
|
|
|
|
defaultStorageQuota: 0,
|
|
|
|
enabled: false,
|
|
|
|
issuerUrl: '',
|
|
|
|
mobileOverrideEnabled: false,
|
|
|
|
mobileRedirectUri: '',
|
|
|
|
scope: 'openid email profile',
|
|
|
|
signingAlgorithm: 'RS256',
|
2024-07-11 13:55:00 +02:00
|
|
|
profileSigningAlgorithm: 'none',
|
2024-05-14 20:43:49 +02:00
|
|
|
storageLabelClaim: 'preferred_username',
|
|
|
|
storageQuotaClaim: 'immich_quota',
|
|
|
|
},
|
|
|
|
passwordLogin: {
|
|
|
|
enabled: true,
|
|
|
|
},
|
|
|
|
storageTemplate: {
|
|
|
|
enabled: false,
|
|
|
|
hashVerificationEnabled: true,
|
|
|
|
template: '{{y}}/{{y}}-{{MM}}-{{dd}}/{{filename}}',
|
|
|
|
},
|
|
|
|
image: {
|
2024-09-28 08:01:04 +02:00
|
|
|
thumbnail: {
|
|
|
|
format: ImageFormat.WEBP,
|
|
|
|
size: 250,
|
|
|
|
quality: 80,
|
|
|
|
},
|
|
|
|
preview: {
|
|
|
|
format: ImageFormat.JPEG,
|
|
|
|
size: 1440,
|
|
|
|
quality: 80,
|
|
|
|
},
|
2024-05-14 20:43:49 +02:00
|
|
|
colorspace: Colorspace.P3,
|
|
|
|
extractEmbedded: false,
|
|
|
|
},
|
|
|
|
newVersionCheck: {
|
|
|
|
enabled: true,
|
|
|
|
},
|
|
|
|
trash: {
|
|
|
|
enabled: true,
|
|
|
|
days: 30,
|
|
|
|
},
|
|
|
|
theme: {
|
|
|
|
customCss: '',
|
|
|
|
},
|
|
|
|
library: {
|
|
|
|
scan: {
|
|
|
|
enabled: true,
|
|
|
|
cronExpression: CronExpression.EVERY_DAY_AT_MIDNIGHT,
|
|
|
|
},
|
|
|
|
watch: {
|
|
|
|
enabled: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
server: {
|
|
|
|
externalDomain: '',
|
|
|
|
loginPageMessage: '',
|
|
|
|
},
|
|
|
|
notifications: {
|
|
|
|
smtp: {
|
|
|
|
enabled: false,
|
|
|
|
from: '',
|
|
|
|
replyTo: '',
|
|
|
|
transport: {
|
|
|
|
ignoreCert: false,
|
|
|
|
host: '',
|
|
|
|
port: 587,
|
|
|
|
username: '',
|
|
|
|
password: '',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
user: {
|
|
|
|
deleteDelay: 7,
|
|
|
|
},
|
|
|
|
});
|
2024-03-20 21:04:03 +01:00
|
|
|
|
|
|
|
const WHEN_DB_URL_SET = Joi.when('DB_URL', {
|
|
|
|
is: Joi.exist(),
|
|
|
|
then: Joi.string().optional(),
|
|
|
|
otherwise: Joi.string().required(),
|
|
|
|
});
|
|
|
|
|
|
|
|
export const immichAppConfig: ConfigModuleOptions = {
|
|
|
|
envFilePath: '.env',
|
|
|
|
isGlobal: true,
|
|
|
|
validationSchema: Joi.object({
|
2024-07-01 19:43:16 +02:00
|
|
|
IMMICH_ENV: Joi.string().optional().valid('development', 'testing', 'production').default('production'),
|
2024-05-17 17:44:22 +02:00
|
|
|
IMMICH_LOG_LEVEL: Joi.string()
|
2024-03-20 21:04:03 +01:00
|
|
|
.optional()
|
|
|
|
.valid(...Object.values(LogLevel)),
|
|
|
|
|
|
|
|
DB_USERNAME: WHEN_DB_URL_SET,
|
|
|
|
DB_PASSWORD: WHEN_DB_URL_SET,
|
|
|
|
DB_DATABASE_NAME: WHEN_DB_URL_SET,
|
|
|
|
DB_URL: Joi.string().optional(),
|
|
|
|
DB_VECTOR_EXTENSION: Joi.string().optional().valid('pgvector', 'pgvecto.rs').default('pgvecto.rs'),
|
2024-04-25 04:52:38 +02:00
|
|
|
DB_SKIP_MIGRATIONS: Joi.boolean().optional().default(false),
|
2024-03-20 21:04:03 +01:00
|
|
|
|
2024-05-17 18:59:05 +02:00
|
|
|
IMMICH_PORT: Joi.number().optional(),
|
2024-06-10 18:01:04 +02:00
|
|
|
IMMICH_API_METRICS_PORT: Joi.number().optional(),
|
|
|
|
IMMICH_MICROSERVICES_METRICS_PORT: Joi.number().optional(),
|
2024-03-20 21:04:03 +01:00
|
|
|
|
2024-07-26 16:23:58 +02:00
|
|
|
IMMICH_TRUSTED_PROXIES: Joi.extend((joi: Root) => ({
|
|
|
|
type: 'stringArray',
|
|
|
|
base: joi.array(),
|
|
|
|
coerce: (value) => (value.split ? value.split(',') : value),
|
|
|
|
}))
|
|
|
|
.stringArray()
|
|
|
|
.single()
|
|
|
|
.items(
|
|
|
|
Joi.string().ip({
|
|
|
|
version: ['ipv4', 'ipv6'],
|
|
|
|
cidr: 'optional',
|
|
|
|
}),
|
|
|
|
),
|
|
|
|
|
2024-03-20 21:04:03 +01:00
|
|
|
IMMICH_METRICS: Joi.boolean().optional().default(false),
|
|
|
|
IMMICH_HOST_METRICS: Joi.boolean().optional().default(false),
|
|
|
|
IMMICH_API_METRICS: Joi.boolean().optional().default(false),
|
|
|
|
IMMICH_IO_METRICS: Joi.boolean().optional().default(false),
|
|
|
|
}),
|
|
|
|
};
|
2023-03-31 16:36:08 +02:00
|
|
|
|
2024-07-03 22:27:29 +02:00
|
|
|
export function parseRedisConfig(): RedisOptions {
|
2023-03-31 22:33:21 +02:00
|
|
|
const redisUrl = process.env.REDIS_URL;
|
|
|
|
if (redisUrl && redisUrl.startsWith('ioredis://')) {
|
|
|
|
try {
|
|
|
|
const decodedString = Buffer.from(redisUrl.slice(10), 'base64').toString();
|
|
|
|
return JSON.parse(decodedString);
|
|
|
|
} catch (error) {
|
|
|
|
throw new Error(`Failed to decode redis options: ${error}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
2024-04-27 17:04:23 +02:00
|
|
|
host: process.env.REDIS_HOSTNAME || 'redis',
|
2024-02-02 04:18:00 +01:00
|
|
|
port: Number.parseInt(process.env.REDIS_PORT || '6379'),
|
|
|
|
db: Number.parseInt(process.env.REDIS_DBINDEX || '0'),
|
2023-03-31 22:33:21 +02:00
|
|
|
username: process.env.REDIS_USERNAME || undefined,
|
|
|
|
password: process.env.REDIS_PASSWORD || undefined,
|
|
|
|
path: process.env.REDIS_SOCKET || undefined,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2023-06-01 12:32:51 +02:00
|
|
|
export const bullConfig: QueueOptions = {
|
2023-03-30 21:38:55 +02:00
|
|
|
prefix: 'immich_bull',
|
2024-01-09 23:07:01 +01:00
|
|
|
connection: parseRedisConfig(),
|
2023-03-30 21:38:55 +02:00
|
|
|
defaultJobOptions: {
|
|
|
|
attempts: 3,
|
|
|
|
removeOnComplete: true,
|
|
|
|
removeOnFail: false,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2023-06-01 12:32:51 +02:00
|
|
|
export const bullQueues: RegisterQueueOptions[] = Object.values(QueueName).map((name) => ({ name }));
|
2024-04-16 01:39:06 +02:00
|
|
|
|
|
|
|
export const clsConfig: ClsModuleOptions = {
|
|
|
|
middleware: {
|
|
|
|
mount: true,
|
|
|
|
generateId: true,
|
|
|
|
setup: (cls, req: Request, res: Response) => {
|
2024-06-05 23:07:47 +02:00
|
|
|
const headerValues = req.headers[ImmichHeader.CID];
|
2024-04-16 01:39:06 +02:00
|
|
|
const headerValue = Array.isArray(headerValues) ? headerValues[0] : headerValues;
|
|
|
|
const cid = headerValue || cls.get(CLS_ID);
|
2024-04-16 23:31:49 +02:00
|
|
|
cls.set(CLS_ID, cid);
|
2024-06-05 23:07:47 +02:00
|
|
|
res.header(ImmichHeader.CID, cid);
|
2024-04-16 01:39:06 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
2024-06-26 14:25:09 +02:00
|
|
|
|
|
|
|
export const getBuildMetadata = () => ({
|
|
|
|
build: process.env.IMMICH_BUILD,
|
|
|
|
buildUrl: process.env.IMMICH_BUILD_URL,
|
|
|
|
buildImage: process.env.IMMICH_BUILD_IMAGE,
|
|
|
|
buildImageUrl: process.env.IMMICH_BUILD_IMAGE_URL,
|
|
|
|
repository: process.env.IMMICH_REPOSITORY,
|
|
|
|
repositoryUrl: process.env.IMMICH_REPOSITORY_URL,
|
|
|
|
sourceRef: process.env.IMMICH_SOURCE_REF,
|
|
|
|
sourceCommit: process.env.IMMICH_SOURCE_COMMIT,
|
|
|
|
sourceUrl: process.env.IMMICH_SOURCE_URL,
|
|
|
|
});
|
2024-07-01 19:43:16 +02:00
|
|
|
|
|
|
|
const clientLicensePublicKeyProd =
|
|
|
|
'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF2LzdTMzJjUkE1KysxTm5WRHNDTQpzcFAvakpISU1xT0pYRm5oNE53QTJPcHorUk1mZGNvOTJQc09naCt3d1FlRXYxVTJjMnBqelRpUS8ybHJLcS9rCnpKUmxYd2M0Y1Vlc1FETUpPRitQMnFPTlBiQUprWHZDWFlCVUxpdENJa29Md2ZoU0dOanlJS2FSRGhkL3ROeU4KOCtoTlJabllUMWhTSWo5U0NrS3hVQ096YXRQVjRtQ0RlclMrYkUrZ0VVZVdwOTlWOWF6dkYwRkltblRXcFFTdwpjOHdFWmdPTWg0c3ZoNmFpY3dkemtQQ3dFTGFrMFZhQkgzMUJFVUNRTGI5K0FJdEhBVXRKQ0t4aGI1V2pzMXM5CmJyWGZpMHZycGdjWi82RGFuWTJxZlNQem5PbXZEMkZycmxTMXE0SkpOM1ZvN1d3LzBZeS95TWNtelRXWmhHdWgKVVFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tDQo=';
|
|
|
|
|
|
|
|
const clientLicensePublicKeyStaging =
|
|
|
|
'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFuSUNyTm5jbGpPSC9JdTNtWVVaRQp0dGJLV1c3OGRuajl5M0U2ekk3dU1NUndEckdYWFhkTGhkUDFxSWtlZHh0clVVeUpCMWR4R04yQW91S082MlNGCldrbU9PTmNGQlRBWFZTdjhUNVY0S0VwWnFQYWEwaXpNaGxMaE5sRXEvY1ZKdllrWlh1Z2x6b1o3cG1nbzFSdHgKam1iRm5NNzhrYTFRUUJqOVdLaEw2eWpWRUl2MDdVS0lKWHBNTnNuS2g1V083MjZhYmMzSE9udTlETjY5VnFFRQo3dGZrUnRWNmx2U1NzMkFVMngzT255cHA4ek53b0lPTWRibGsyb09aWWROZzY0Y3l2SzJoU0FlU3NVMFRyOVc5Ckgra0Y5QlNCNlk0QXl0QlVkSmkrK2pMSW5HM2Q5cU9ieFVzTlYrN05mRkF5NjJkL0xNR0xSOC9OUFc0U0s3c0MKRlFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tDQo=';
|
|
|
|
|
|
|
|
export const getClientLicensePublicKey = (): string => {
|
|
|
|
if (process.env.IMMICH_ENV === 'production') {
|
|
|
|
return clientLicensePublicKeyProd;
|
|
|
|
}
|
|
|
|
return clientLicensePublicKeyStaging;
|
|
|
|
};
|
|
|
|
|
|
|
|
const serverLicensePublicKeyProd =
|
|
|
|
'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFvcG5ZRGEwYS9kVTVJZUc3NGlFRQpNd2RBS2pzTmN6TGRDcVJkMVo5eTVUMndqTzdlWUlPZUpUc2wzNTBzUjBwNEtmU1VEU1h2QzlOcERwYzF0T0tsCjVzaEMvQXhwdlFBTENva0Y0anQ4dnJyZDlmQ2FYYzFUcVJiT21uaGl1Z0Q2dmtyME8vRmIzVURpM1UwVHZoUFAKbFBkdlNhd3pMcldaUExmbUhWVnJiclNLbW45SWVTZ3kwN3VrV1RJeUxzY2lOcnZuQnl3c0phUmVEdW9OV1BCSApVL21vMm1YYThtNHdNV2hpWGVoaUlPUXFNdVNVZ1BlQ3NXajhVVngxQ0dsUnpQREEwYlZOUXZlS1hXVnhjRUk2ClVMRWdKeTJGNDlsSDArYVlDbUJmN05FcjZWUTJXQjk1ZXZUS1hLdm4wcUlNN25nRmxjVUF3NmZ1VjFjTkNUSlMKNndJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tDQo=';
|
|
|
|
|
|
|
|
const serverLicensePublicKeyStaging =
|
|
|
|
'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUE3Sy8yd3ZLUS9NdU8ydi9MUm5saAoyUy9zTHhDOGJiTEw1UUlKOGowQ3BVZW40YURlY2dYMUpKUmtGNlpUVUtpNTdTbEhtS3RSM2JOTzJmdTBUUVg5Ck5WMEJzVzllZVB0MmlTMWl4VVFmTzRObjdvTjZzbEtac01qd29RNGtGRGFmM3VHTlZJc0dMb3UxVWRLUVhpeDEKUlRHcXVTb3NZVjNWRlk3Q1hGYTVWaENBL3poVXNsNGFuVXp3eEF6M01jUFVlTXBaenYvbVZiQlRKVzBPSytWZgpWQUJvMXdYMkVBanpBekVHVzQ3Vko4czhnMnQrNHNPaHFBNStMQjBKVzlORUg5QUpweGZzWE4zSzVtM00yNUJVClZXcTlRYStIdHRENnJ0bnAvcUFweXVkWUdwZk9HYTRCUlZTR1MxMURZM0xrb2FlRzYwUEU5NHpoYjduOHpMWkgKelFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tDQo=';
|
|
|
|
|
|
|
|
export const getServerLicensePublicKey = (): string => {
|
|
|
|
if (process.env.IMMICH_ENV === 'production') {
|
|
|
|
return serverLicensePublicKeyProd;
|
|
|
|
}
|
|
|
|
return serverLicensePublicKeyStaging;
|
|
|
|
};
|