Merge branch 'main' into feature/readonly-sharing
# Conflicts: # e2e/src/utils.ts # mobile/openapi/.openapi-generator/FILES # mobile/openapi/README.md # mobile/openapi/lib/api.dart # mobile/openapi/lib/api_client.dart
This commit is contained in:
@@ -37,15 +37,15 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-java@v4
|
- uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: "zulu"
|
distribution: 'zulu'
|
||||||
java-version: "11.0.21+9"
|
java-version: '17'
|
||||||
cache: "gradle"
|
cache: 'gradle'
|
||||||
|
|
||||||
- name: Setup Flutter SDK
|
- name: Setup Flutter SDK
|
||||||
uses: subosito/flutter-action@v2
|
uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
channel: "stable"
|
channel: 'stable'
|
||||||
flutter-version: "3.19.3"
|
flutter-version: '3.19.3'
|
||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
- name: Create the Keystore
|
- name: Create the Keystore
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ jobs:
|
|||||||
uses: subosito/flutter-action@v2
|
uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
channel: 'stable'
|
channel: 'stable'
|
||||||
flutter-version: '3.16.9'
|
flutter-version: '3.19.3'
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
working-directory: ./mobile
|
working-directory: ./mobile
|
||||||
run: flutter test -j 1
|
run: flutter test -j 1
|
||||||
|
|||||||
Generated
+3
-3
@@ -47,15 +47,15 @@
|
|||||||
},
|
},
|
||||||
"../open-api/typescript-sdk": {
|
"../open-api/typescript-sdk": {
|
||||||
"name": "@immich/sdk",
|
"name": "@immich/sdk",
|
||||||
"version": "1.101.0",
|
"version": "1.102.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@oazapfts/runtime": "^1.0.2"
|
"@oazapfts/runtime": "^1.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.12.7",
|
"@types/node": "^20.11.0",
|
||||||
"typescript": "^5.4.5"
|
"typescript": "^5.3.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@aashutoshrathi/word-wrap": {
|
"node_modules/@aashutoshrathi/word-wrap": {
|
||||||
|
|||||||
@@ -120,7 +120,8 @@ The default configuration looks like this:
|
|||||||
"previewFormat": "jpeg",
|
"previewFormat": "jpeg",
|
||||||
"previewSize": 1440,
|
"previewSize": 1440,
|
||||||
"quality": 80,
|
"quality": 80,
|
||||||
"colorspace": "p3"
|
"colorspace": "p3",
|
||||||
|
"extractEmbedded": false
|
||||||
},
|
},
|
||||||
"newVersionCheck": {
|
"newVersionCheck": {
|
||||||
"enabled": true
|
"enabled": true
|
||||||
|
|||||||
Generated
+5
-5
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "immich-e2e",
|
"name": "immich-e2e",
|
||||||
"version": "1.101.0",
|
"version": "1.102.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "immich-e2e",
|
"name": "immich-e2e",
|
||||||
"version": "1.101.0",
|
"version": "1.102.3",
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@immich/cli": "file:../cli",
|
"@immich/cli": "file:../cli",
|
||||||
@@ -81,15 +81,15 @@
|
|||||||
},
|
},
|
||||||
"../open-api/typescript-sdk": {
|
"../open-api/typescript-sdk": {
|
||||||
"name": "@immich/sdk",
|
"name": "@immich/sdk",
|
||||||
"version": "1.101.0",
|
"version": "1.102.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@oazapfts/runtime": "^1.0.2"
|
"@oazapfts/runtime": "^1.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.12.7",
|
"@types/node": "^20.11.0",
|
||||||
"typescript": "^5.4.5"
|
"typescript": "^5.3.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@aashutoshrathi/word-wrap": {
|
"node_modules/@aashutoshrathi/word-wrap": {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "immich-e2e",
|
"name": "immich-e2e",
|
||||||
"version": "1.101.0",
|
"version": "1.102.3",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -112,9 +112,29 @@ describe('/auth/*', () => {
|
|||||||
|
|
||||||
const cookies = headers['set-cookie'];
|
const cookies = headers['set-cookie'];
|
||||||
expect(cookies).toHaveLength(3);
|
expect(cookies).toHaveLength(3);
|
||||||
expect(cookies[0]).toEqual(`immich_access_token=${token}; HttpOnly; Path=/; Max-Age=34560000; SameSite=Lax;`);
|
expect(cookies[0].split(';').map((item) => item.trim())).toEqual([
|
||||||
expect(cookies[1]).toEqual('immich_auth_type=password; HttpOnly; Path=/; Max-Age=34560000; SameSite=Lax;');
|
`immich_access_token=${token}`,
|
||||||
expect(cookies[2]).toEqual('immich_is_authenticated=true; Path=/; Max-Age=34560000; SameSite=Lax;');
|
'Max-Age=34560000',
|
||||||
|
'Path=/',
|
||||||
|
expect.stringContaining('Expires='),
|
||||||
|
'HttpOnly',
|
||||||
|
'SameSite=Lax',
|
||||||
|
]);
|
||||||
|
expect(cookies[1].split(';').map((item) => item.trim())).toEqual([
|
||||||
|
'immich_auth_type=password',
|
||||||
|
'Max-Age=34560000',
|
||||||
|
'Path=/',
|
||||||
|
expect.stringContaining('Expires='),
|
||||||
|
'HttpOnly',
|
||||||
|
'SameSite=Lax',
|
||||||
|
]);
|
||||||
|
expect(cookies[2].split(';').map((item) => item.trim())).toEqual([
|
||||||
|
'immich_is_authenticated=true',
|
||||||
|
'Max-Age=34560000',
|
||||||
|
'Path=/',
|
||||||
|
expect.stringContaining('Expires='),
|
||||||
|
'SameSite=Lax',
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { LoginResponseDto, getServerConfig } from '@immich/sdk';
|
import { LoginResponseDto } from '@immich/sdk';
|
||||||
import { createUserDto } from 'src/fixtures';
|
import { createUserDto } from 'src/fixtures';
|
||||||
import { errorDto } from 'src/responses';
|
import { errorDto } from 'src/responses';
|
||||||
import { app, utils } from 'src/utils';
|
import { app, utils } from 'src/utils';
|
||||||
@@ -162,19 +162,4 @@ describe('/server-info', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /server-info/admin-onboarding', () => {
|
|
||||||
it('should set admin onboarding', async () => {
|
|
||||||
const config = await getServerConfig({});
|
|
||||||
expect(config.isOnboarded).toBe(false);
|
|
||||||
|
|
||||||
const { status } = await request(app)
|
|
||||||
.post('/server-info/admin-onboarding')
|
|
||||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
|
||||||
expect(status).toBe(204);
|
|
||||||
|
|
||||||
const newConfig = await getServerConfig({});
|
|
||||||
expect(newConfig.isOnboarded).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
import { LoginResponseDto, getServerConfig } from '@immich/sdk';
|
||||||
|
import { createUserDto } from 'src/fixtures';
|
||||||
|
import { errorDto } from 'src/responses';
|
||||||
|
import { app, utils } from 'src/utils';
|
||||||
|
import request from 'supertest';
|
||||||
|
import { beforeAll, describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
|
describe('/server-info', () => {
|
||||||
|
let admin: LoginResponseDto;
|
||||||
|
let nonAdmin: LoginResponseDto;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await utils.resetDatabase();
|
||||||
|
admin = await utils.adminSetup({ onboarding: false });
|
||||||
|
nonAdmin = await utils.userSetup(admin.accessToken, createUserDto.user1);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('POST /system-metadata/admin-onboarding', () => {
|
||||||
|
it('should require authentication', async () => {
|
||||||
|
const { status, body } = await request(app).post('/system-metadata/admin-onboarding').send({ isOnboarded: true });
|
||||||
|
expect(status).toBe(401);
|
||||||
|
expect(body).toEqual(errorDto.unauthorized);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should only work for admins', async () => {
|
||||||
|
const { status, body } = await request(app)
|
||||||
|
.post('/system-metadata/admin-onboarding')
|
||||||
|
.set('Authorization', `Bearer ${nonAdmin.accessToken}`)
|
||||||
|
.send({ isOnboarded: true });
|
||||||
|
expect(status).toBe(403);
|
||||||
|
expect(body).toEqual(errorDto.forbidden);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set admin onboarding', async () => {
|
||||||
|
const config = await getServerConfig({});
|
||||||
|
expect(config.isOnboarded).toBe(false);
|
||||||
|
|
||||||
|
const { status } = await request(app)
|
||||||
|
.post('/system-metadata/admin-onboarding')
|
||||||
|
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||||
|
.send({ isOnboarded: true });
|
||||||
|
expect(status).toBe(204);
|
||||||
|
|
||||||
|
const newConfig = await getServerConfig({});
|
||||||
|
expect(newConfig.isOnboarded).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('GET /system-metadata/reverse-geocoding-state', () => {
|
||||||
|
it('should require authentication', async () => {
|
||||||
|
const { status, body } = await request(app).get('/system-metadata/reverse-geocoding-state');
|
||||||
|
expect(status).toBe(401);
|
||||||
|
expect(body).toEqual(errorDto.unauthorized);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should only work for admins', async () => {
|
||||||
|
const { status, body } = await request(app)
|
||||||
|
.get('/system-metadata/reverse-geocoding-state')
|
||||||
|
.set('Authorization', `Bearer ${nonAdmin.accessToken}`);
|
||||||
|
expect(status).toBe(403);
|
||||||
|
expect(body).toEqual(errorDto.forbidden);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get the reverse geocoding state', async () => {
|
||||||
|
const { status, body } = await request(app)
|
||||||
|
.get('/system-metadata/reverse-geocoding-state')
|
||||||
|
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||||
|
|
||||||
|
expect(status).toBe(200);
|
||||||
|
expect(body).toEqual({
|
||||||
|
lastUpdate: expect.any(String),
|
||||||
|
lastImportFileName: 'cities500.txt',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
+5
-2
@@ -24,8 +24,8 @@ import {
|
|||||||
getConfigDefaults,
|
getConfigDefaults,
|
||||||
login,
|
login,
|
||||||
searchMetadata,
|
searchMetadata,
|
||||||
setAdminOnboarding,
|
|
||||||
signUpAdmin,
|
signUpAdmin,
|
||||||
|
updateAdminOnboarding,
|
||||||
updateAlbumUser,
|
updateAlbumUser,
|
||||||
updateConfig,
|
updateConfig,
|
||||||
validate,
|
validate,
|
||||||
@@ -265,7 +265,10 @@ export const utils = {
|
|||||||
await signUpAdmin({ signUpDto: signupDto.admin });
|
await signUpAdmin({ signUpDto: signupDto.admin });
|
||||||
const response = await login({ loginCredentialDto: loginDto.admin });
|
const response = await login({ loginCredentialDto: loginDto.admin });
|
||||||
if (options.onboarding) {
|
if (options.onboarding) {
|
||||||
await setAdminOnboarding({ headers: asBearerAuth(response.accessToken) });
|
await updateAdminOnboarding(
|
||||||
|
{ adminOnboardingUpdateDto: { isOnboarded: true } },
|
||||||
|
{ headers: asBearerAuth(response.accessToken) },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "machine-learning"
|
name = "machine-learning"
|
||||||
version = "1.101.0"
|
version = "1.102.3"
|
||||||
description = ""
|
description = ""
|
||||||
authors = ["Hau Tran <alex.tran1502@gmail.com>"]
|
authors = ["Hau Tran <alex.tran1502@gmail.com>"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
|
plugins {
|
||||||
|
id "com.android.application"
|
||||||
|
id "kotlin-android"
|
||||||
|
id "dev.flutter.flutter-gradle-plugin"
|
||||||
|
id "kotlin-kapt"
|
||||||
|
}
|
||||||
|
|
||||||
def localProperties = new Properties()
|
def localProperties = new Properties()
|
||||||
def localPropertiesFile = rootProject.file('local.properties')
|
def localPropertiesFile = rootProject.file('local.properties')
|
||||||
if (localPropertiesFile.exists()) {
|
if (localPropertiesFile.exists()) {
|
||||||
localPropertiesFile.withReader('UTF-8') { reader ->
|
localPropertiesFile.withInputStream { localProperties.load(it) }
|
||||||
localProperties.load(reader)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
|
||||||
if (flutterRoot == null) {
|
|
||||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||||
@@ -21,18 +21,12 @@ if (flutterVersionName == null) {
|
|||||||
flutterVersionName = '1.0'
|
flutterVersionName = '1.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
|
||||||
apply plugin: 'kotlin-android'
|
|
||||||
apply plugin: 'kotlin-kapt'
|
|
||||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
|
||||||
|
|
||||||
def keystoreProperties = new Properties()
|
def keystoreProperties = new Properties()
|
||||||
def keystorePropertiesFile = rootProject.file('key.properties')
|
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||||
if (keystorePropertiesFile.exists()) {
|
if (keystorePropertiesFile.exists()) {
|
||||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
keystorePropertiesFile.withInputStream { keystoreProperties.load(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 34
|
compileSdkVersion 34
|
||||||
|
|
||||||
@@ -50,7 +44,6 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
|
||||||
applicationId "app.alextran.immich"
|
applicationId "app.alextran.immich"
|
||||||
minSdkVersion 26
|
minSdkVersion 26
|
||||||
targetSdkVersion 33
|
targetSdkVersion 33
|
||||||
@@ -88,6 +81,13 @@ flutter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
def kotlin_version = '1.9.23'
|
||||||
|
def kotlin_coroutines_version = '1.8.0'
|
||||||
|
def work_version = '2.9.0'
|
||||||
|
def concurrent_version = '1.1.0'
|
||||||
|
def guava_version = '33.1.0-android'
|
||||||
|
def glide_version = '4.16.0'
|
||||||
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
|
||||||
implementation "androidx.work:work-runtime-ktx:$work_version"
|
implementation "androidx.work:work-runtime-ktx:$work_version"
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ class BackupWorker(ctx: Context, params: WorkerParameters) : ListenableWorker(ct
|
|||||||
private const val NOTIFICATION_CHANNEL_ERROR_ID = "immich/backgroundServiceError"
|
private const val NOTIFICATION_CHANNEL_ERROR_ID = "immich/backgroundServiceError"
|
||||||
private const val NOTIFICATION_DEFAULT_TITLE = "Immich"
|
private const val NOTIFICATION_DEFAULT_TITLE = "Immich"
|
||||||
private const val NOTIFICATION_ID = 1
|
private const val NOTIFICATION_ID = 1
|
||||||
private const val NOTIFICATION_ERROR_ID = 2
|
private const val NOTIFICATION_ERROR_ID = 2
|
||||||
private const val NOTIFICATION_DETAIL_ID = 3
|
private const val NOTIFICATION_DETAIL_ID = 3
|
||||||
private const val ONE_MINUTE = 60000L
|
private const val ONE_MINUTE = 60000L
|
||||||
|
|
||||||
@@ -304,7 +304,7 @@ class BackupWorker(ctx: Context, params: WorkerParameters) : ListenableWorker(ct
|
|||||||
val workInfoList = workInfoFuture.get(1000, TimeUnit.MILLISECONDS)
|
val workInfoList = workInfoFuture.get(1000, TimeUnit.MILLISECONDS)
|
||||||
if (workInfoList != null) {
|
if (workInfoList != null) {
|
||||||
for (workInfo in workInfoList) {
|
for (workInfo in workInfoList) {
|
||||||
if (workInfo.getState() == WorkInfo.State.ENQUEUED) {
|
if (workInfo.state == WorkInfo.State.ENQUEUED) {
|
||||||
val workRequest = buildWorkRequest(requireWifi, requireCharging)
|
val workRequest = buildWorkRequest(requireWifi, requireCharging)
|
||||||
wm.enqueueUniqueWork(TASK_NAME_BACKUP, ExistingWorkPolicy.REPLACE, workRequest)
|
wm.enqueueUniqueWork(TASK_NAME_BACKUP, ExistingWorkPolicy.REPLACE, workRequest)
|
||||||
Log.d(TAG, "updateBackupWorker updated BackupWorker constraints")
|
Log.d(TAG, "updateBackupWorker updated BackupWorker constraints")
|
||||||
@@ -346,7 +346,7 @@ class BackupWorker(ctx: Context, params: WorkerParameters) : ListenableWorker(ct
|
|||||||
.setRequiresBatteryNotLow(true)
|
.setRequiresBatteryNotLow(true)
|
||||||
.setRequiresCharging(requireCharging)
|
.setRequiresCharging(requireCharging)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
val work = OneTimeWorkRequest.Builder(BackupWorker::class.java)
|
val work = OneTimeWorkRequest.Builder(BackupWorker::class.java)
|
||||||
.setConstraints(constraints)
|
.setConstraints(constraints)
|
||||||
.setBackoffCriteria(BackoffPolicy.EXPONENTIAL, ONE_MINUTE, TimeUnit.MILLISECONDS)
|
.setBackoffCriteria(BackoffPolicy.EXPONENTIAL, ONE_MINUTE, TimeUnit.MILLISECONDS)
|
||||||
@@ -359,4 +359,4 @@ class BackupWorker(ctx: Context, params: WorkerParameters) : ListenableWorker(ct
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val TAG = "BackupWorker"
|
private const val TAG = "BackupWorker"
|
||||||
|
|||||||
@@ -1,21 +1,3 @@
|
|||||||
buildscript {
|
|
||||||
ext.kotlin_version = '1.8.20'
|
|
||||||
ext.kotlin_coroutines_version = '1.7.1'
|
|
||||||
ext.work_version = '2.7.1'
|
|
||||||
ext.concurrent_version = '1.1.0'
|
|
||||||
ext.guava_version = '33.0.0-android'
|
|
||||||
ext.glide_version = '4.14.2'
|
|
||||||
repositories {
|
|
||||||
google()
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.android.tools.build:gradle:7.4.2'
|
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
@@ -34,3 +16,7 @@ subprojects {
|
|||||||
tasks.register("clean", Delete) {
|
tasks.register("clean", Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.named('wrapper') {
|
||||||
|
distributionType = Wrapper.DistributionType.ALL
|
||||||
|
}
|
||||||
@@ -35,8 +35,8 @@ platform :android do
|
|||||||
task: 'bundle',
|
task: 'bundle',
|
||||||
build_type: 'Release',
|
build_type: 'Release',
|
||||||
properties: {
|
properties: {
|
||||||
"android.injected.version.code" => 131,
|
"android.injected.version.code" => 136,
|
||||||
"android.injected.version.name" => "1.101.0",
|
"android.injected.version.name" => "1.102.3",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab')
|
upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab')
|
||||||
|
|||||||
@@ -5,17 +5,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000219">
|
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000261">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="1: bundleRelease" time="67.515419">
|
<testcase classname="fastlane.lanes" name="1: bundleRelease" time="32.48099">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="2: upload_to_play_store" time="35.431743">
|
<testcase classname="fastlane.lanes" name="2: upload_to_play_store" time="30.236974">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -1,6 +1,7 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.4-all.zip
|
||||||
distributionSha256Sum=6001aba9b2204d26fa25a5800bb9382cf3ee01ccb78fe77317b2872336eb2f80
|
distributionSha256Sum=fe696c020f241a5f69c30f763c5a7f38eec54b490db19cd2b0962dda420d7d12
|
||||||
@@ -1,11 +1,26 @@
|
|||||||
include ':app'
|
pluginManagement {
|
||||||
|
def flutterSdkPath = {
|
||||||
|
def properties = new Properties()
|
||||||
|
file("local.properties").withInputStream { properties.load(it) }
|
||||||
|
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||||
|
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
||||||
|
return flutterSdkPath
|
||||||
|
}()
|
||||||
|
|
||||||
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
|
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||||
def properties = new Properties()
|
|
||||||
|
|
||||||
assert localPropertiesFile.exists()
|
repositories {
|
||||||
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
plugins {
|
||||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||||
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
|
id "com.android.application" version "7.4.2" apply false
|
||||||
|
id "org.jetbrains.kotlin.android" version "1.9.23" apply false
|
||||||
|
id "org.jetbrains.kotlin.kapt" version "1.9.23" apply false
|
||||||
|
}
|
||||||
|
|
||||||
|
include ":app"
|
||||||
|
|||||||
@@ -296,6 +296,7 @@
|
|||||||
"motion_photos_page_title": "Motion Photos",
|
"motion_photos_page_title": "Motion Photos",
|
||||||
"multiselect_grid_edit_date_time_err_read_only": "Cannot edit date of read only asset(s), skipping",
|
"multiselect_grid_edit_date_time_err_read_only": "Cannot edit date of read only asset(s), skipping",
|
||||||
"multiselect_grid_edit_gps_err_read_only": "Cannot edit location of read only asset(s), skipping",
|
"multiselect_grid_edit_gps_err_read_only": "Cannot edit location of read only asset(s), skipping",
|
||||||
|
"no_assets_to_show" : "No assets to show",
|
||||||
"notification_permission_dialog_cancel": "Cancel",
|
"notification_permission_dialog_cancel": "Cancel",
|
||||||
"notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.",
|
"notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.",
|
||||||
"notification_permission_dialog_settings": "Settings",
|
"notification_permission_dialog_settings": "Settings",
|
||||||
|
|||||||
@@ -296,6 +296,7 @@
|
|||||||
"motion_photos_page_title": "Photos avec mouvement",
|
"motion_photos_page_title": "Photos avec mouvement",
|
||||||
"multiselect_grid_edit_date_time_err_read_only": "Impossible de modifier la date d'un élément d'actif en lecture seule.",
|
"multiselect_grid_edit_date_time_err_read_only": "Impossible de modifier la date d'un élément d'actif en lecture seule.",
|
||||||
"multiselect_grid_edit_gps_err_read_only": "Impossible de modifier l'emplacement d'un élément en lecture seule.",
|
"multiselect_grid_edit_gps_err_read_only": "Impossible de modifier l'emplacement d'un élément en lecture seule.",
|
||||||
|
"no_assets_to_show" : "Aucun élément à afficher",
|
||||||
"notification_permission_dialog_cancel": "Annuler",
|
"notification_permission_dialog_cancel": "Annuler",
|
||||||
"notification_permission_dialog_content": "Pour activer les notifications, allez dans Paramètres et sélectionnez Autoriser.",
|
"notification_permission_dialog_content": "Pour activer les notifications, allez dans Paramètres et sélectionnez Autoriser.",
|
||||||
"notification_permission_dialog_settings": "Paramètres",
|
"notification_permission_dialog_settings": "Paramètres",
|
||||||
@@ -509,5 +510,7 @@
|
|||||||
"version_announcement_overlay_title": "Nouvelle version serveur disponible \uD83C\uDF89",
|
"version_announcement_overlay_title": "Nouvelle version serveur disponible \uD83C\uDF89",
|
||||||
"viewer_remove_from_stack": "Retirer de la pile",
|
"viewer_remove_from_stack": "Retirer de la pile",
|
||||||
"viewer_stack_use_as_main_asset": "Utiliser comme élément principal",
|
"viewer_stack_use_as_main_asset": "Utiliser comme élément principal",
|
||||||
"viewer_unstack": "Désempiler"
|
"viewer_unstack": "Désempiler",
|
||||||
|
"haptic_feedback_title": "Retour haptique",
|
||||||
|
"haptic_feedback_switch": "Activer le retour haptique"
|
||||||
}
|
}
|
||||||
@@ -383,7 +383,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerProfile.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/RunnerProfile.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 147;
|
CURRENT_PROJECT_VERSION = 150;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -525,7 +525,7 @@
|
|||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 147;
|
CURRENT_PROJECT_VERSION = 150;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -553,7 +553,7 @@
|
|||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 147;
|
CURRENT_PROJECT_VERSION = 150;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
|||||||
@@ -58,11 +58,11 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.101.0</string>
|
<string>1.102.2</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>147</string>
|
<string>150</string>
|
||||||
<key>FLTEnableImpeller</key>
|
<key>FLTEnableImpeller</key>
|
||||||
<true />
|
<true />
|
||||||
<key>ITSAppUsesNonExemptEncryption</key>
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ platform :ios do
|
|||||||
desc "iOS Beta"
|
desc "iOS Beta"
|
||||||
lane :beta do
|
lane :beta do
|
||||||
increment_version_number(
|
increment_version_number(
|
||||||
version_number: "1.101.0"
|
version_number: "1.102.3"
|
||||||
)
|
)
|
||||||
increment_build_number(
|
increment_build_number(
|
||||||
build_number: latest_testflight_build_number + 1,
|
build_number: latest_testflight_build_number + 1,
|
||||||
|
|||||||
@@ -5,32 +5,32 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000242">
|
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000231">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="1: increment_version_number" time="0.761829">
|
<testcase classname="fastlane.lanes" name="1: increment_version_number" time="0.155919">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="2: latest_testflight_build_number" time="4.47461">
|
<testcase classname="fastlane.lanes" name="2: latest_testflight_build_number" time="4.252784">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="3: increment_build_number" time="0.179512">
|
<testcase classname="fastlane.lanes" name="3: increment_build_number" time="0.210502">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="4: build_app" time="165.636347">
|
<testcase classname="fastlane.lanes" name="4: build_app" time="175.813647">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="5: upload_to_testflight" time="77.651963">
|
<testcase classname="fastlane.lanes" name="5: upload_to_testflight" time="73.512517">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class MultiselectGrid extends HookConsumerWidget {
|
|||||||
const Center(child: ImmichLoadingIndicator());
|
const Center(child: ImmichLoadingIndicator());
|
||||||
|
|
||||||
Widget buildEmptyIndicator() =>
|
Widget buildEmptyIndicator() =>
|
||||||
emptyIndicator ?? const Center(child: Text("No assets to show"));
|
emptyIndicator ?? Center(child: const Text("no_assets_to_show").tr());
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ class SplashScreenPage extends HookConsumerWidget {
|
|||||||
void performLoggingIn() async {
|
void performLoggingIn() async {
|
||||||
bool isSuccess = false;
|
bool isSuccess = false;
|
||||||
bool deviceIsOffline = false;
|
bool deviceIsOffline = false;
|
||||||
|
|
||||||
if (accessToken != null && serverUrl != null) {
|
if (accessToken != null && serverUrl != null) {
|
||||||
try {
|
try {
|
||||||
// Resolve API server endpoint from user provided serverUrl
|
// Resolve API server endpoint from user provided serverUrl
|
||||||
@@ -51,11 +50,15 @@ class SplashScreenPage extends HookConsumerWidget {
|
|||||||
offlineLogin: deviceIsOffline,
|
offlineLogin: deviceIsOffline,
|
||||||
);
|
);
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stackTrace) {
|
||||||
|
ref.read(authenticationProvider.notifier).logout();
|
||||||
|
|
||||||
log.severe(
|
log.severe(
|
||||||
'Cannot set success login info',
|
'Cannot set success login info',
|
||||||
error,
|
error,
|
||||||
stackTrace,
|
stackTrace,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
context.pushRoute(const LoginRoute());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,11 +76,6 @@ class SplashScreenPage extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
context.replaceRoute(const TabControllerRoute());
|
context.replaceRoute(const TabControllerRoute());
|
||||||
} else {
|
} else {
|
||||||
log.severe(
|
|
||||||
'Unable to login through offline or online methods - logging out completely',
|
|
||||||
);
|
|
||||||
|
|
||||||
ref.read(authenticationProvider.notifier).logout();
|
|
||||||
// User was unable to login through either offline or online methods
|
// User was unable to login through either offline or online methods
|
||||||
context.replaceRoute(const LoginRoute());
|
context.replaceRoute(const LoginRoute());
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+12
-9
@@ -13,11 +13,10 @@ doc/ActivityCreateDto.md
|
|||||||
doc/ActivityResponseDto.md
|
doc/ActivityResponseDto.md
|
||||||
doc/ActivityStatisticsResponseDto.md
|
doc/ActivityStatisticsResponseDto.md
|
||||||
doc/AddUsersDto.md
|
doc/AddUsersDto.md
|
||||||
|
doc/AdminOnboardingUpdateDto.md
|
||||||
doc/AlbumApi.md
|
doc/AlbumApi.md
|
||||||
doc/AlbumCountResponseDto.md
|
doc/AlbumCountResponseDto.md
|
||||||
doc/AlbumResponseDto.md
|
doc/AlbumResponseDto.md
|
||||||
doc/AlbumUserResponseDto.md
|
|
||||||
doc/AlbumUserRole.md
|
|
||||||
doc/AllJobStatusResponseDto.md
|
doc/AllJobStatusResponseDto.md
|
||||||
doc/AssetApi.md
|
doc/AssetApi.md
|
||||||
doc/AssetBulkDeleteDto.md
|
doc/AssetBulkDeleteDto.md
|
||||||
@@ -71,6 +70,7 @@ doc/FaceApi.md
|
|||||||
doc/FaceDto.md
|
doc/FaceDto.md
|
||||||
doc/FileChecksumDto.md
|
doc/FileChecksumDto.md
|
||||||
doc/FileChecksumResponseDto.md
|
doc/FileChecksumResponseDto.md
|
||||||
|
doc/FileReportApi.md
|
||||||
doc/FileReportDto.md
|
doc/FileReportDto.md
|
||||||
doc/FileReportFixDto.md
|
doc/FileReportFixDto.md
|
||||||
doc/FileReportItemDto.md
|
doc/FileReportItemDto.md
|
||||||
@@ -124,6 +124,7 @@ doc/QueueStatusDto.md
|
|||||||
doc/ReactionLevel.md
|
doc/ReactionLevel.md
|
||||||
doc/ReactionType.md
|
doc/ReactionType.md
|
||||||
doc/RecognitionConfig.md
|
doc/RecognitionConfig.md
|
||||||
|
doc/ReverseGeocodingStateResponseDto.md
|
||||||
doc/ScanLibraryDto.md
|
doc/ScanLibraryDto.md
|
||||||
doc/SearchAlbumResponseDto.md
|
doc/SearchAlbumResponseDto.md
|
||||||
doc/SearchApi.md
|
doc/SearchApi.md
|
||||||
@@ -175,6 +176,7 @@ doc/SystemConfigTemplateStorageOptionDto.md
|
|||||||
doc/SystemConfigThemeDto.md
|
doc/SystemConfigThemeDto.md
|
||||||
doc/SystemConfigTrashDto.md
|
doc/SystemConfigTrashDto.md
|
||||||
doc/SystemConfigUserDto.md
|
doc/SystemConfigUserDto.md
|
||||||
|
doc/SystemMetadataApi.md
|
||||||
doc/TagApi.md
|
doc/TagApi.md
|
||||||
doc/TagResponseDto.md
|
doc/TagResponseDto.md
|
||||||
doc/TagTypeEnum.md
|
doc/TagTypeEnum.md
|
||||||
@@ -187,7 +189,6 @@ doc/TranscodeHWAccel.md
|
|||||||
doc/TranscodePolicy.md
|
doc/TranscodePolicy.md
|
||||||
doc/TrashApi.md
|
doc/TrashApi.md
|
||||||
doc/UpdateAlbumDto.md
|
doc/UpdateAlbumDto.md
|
||||||
doc/UpdateAlbumUserDto.md
|
|
||||||
doc/UpdateAssetDto.md
|
doc/UpdateAssetDto.md
|
||||||
doc/UpdateLibraryDto.md
|
doc/UpdateLibraryDto.md
|
||||||
doc/UpdatePartnerDto.md
|
doc/UpdatePartnerDto.md
|
||||||
@@ -215,6 +216,7 @@ lib/api/audit_api.dart
|
|||||||
lib/api/authentication_api.dart
|
lib/api/authentication_api.dart
|
||||||
lib/api/download_api.dart
|
lib/api/download_api.dart
|
||||||
lib/api/face_api.dart
|
lib/api/face_api.dart
|
||||||
|
lib/api/file_report_api.dart
|
||||||
lib/api/job_api.dart
|
lib/api/job_api.dart
|
||||||
lib/api/library_api.dart
|
lib/api/library_api.dart
|
||||||
lib/api/memory_api.dart
|
lib/api/memory_api.dart
|
||||||
@@ -227,6 +229,7 @@ lib/api/sessions_api.dart
|
|||||||
lib/api/shared_link_api.dart
|
lib/api/shared_link_api.dart
|
||||||
lib/api/sync_api.dart
|
lib/api/sync_api.dart
|
||||||
lib/api/system_config_api.dart
|
lib/api/system_config_api.dart
|
||||||
|
lib/api/system_metadata_api.dart
|
||||||
lib/api/tag_api.dart
|
lib/api/tag_api.dart
|
||||||
lib/api/timeline_api.dart
|
lib/api/timeline_api.dart
|
||||||
lib/api/trash_api.dart
|
lib/api/trash_api.dart
|
||||||
@@ -243,10 +246,9 @@ lib/model/activity_create_dto.dart
|
|||||||
lib/model/activity_response_dto.dart
|
lib/model/activity_response_dto.dart
|
||||||
lib/model/activity_statistics_response_dto.dart
|
lib/model/activity_statistics_response_dto.dart
|
||||||
lib/model/add_users_dto.dart
|
lib/model/add_users_dto.dart
|
||||||
|
lib/model/admin_onboarding_update_dto.dart
|
||||||
lib/model/album_count_response_dto.dart
|
lib/model/album_count_response_dto.dart
|
||||||
lib/model/album_response_dto.dart
|
lib/model/album_response_dto.dart
|
||||||
lib/model/album_user_response_dto.dart
|
|
||||||
lib/model/album_user_role.dart
|
|
||||||
lib/model/all_job_status_response_dto.dart
|
lib/model/all_job_status_response_dto.dart
|
||||||
lib/model/api_key_create_dto.dart
|
lib/model/api_key_create_dto.dart
|
||||||
lib/model/api_key_create_response_dto.dart
|
lib/model/api_key_create_response_dto.dart
|
||||||
@@ -346,6 +348,7 @@ lib/model/queue_status_dto.dart
|
|||||||
lib/model/reaction_level.dart
|
lib/model/reaction_level.dart
|
||||||
lib/model/reaction_type.dart
|
lib/model/reaction_type.dart
|
||||||
lib/model/recognition_config.dart
|
lib/model/recognition_config.dart
|
||||||
|
lib/model/reverse_geocoding_state_response_dto.dart
|
||||||
lib/model/scan_library_dto.dart
|
lib/model/scan_library_dto.dart
|
||||||
lib/model/search_album_response_dto.dart
|
lib/model/search_album_response_dto.dart
|
||||||
lib/model/search_asset_response_dto.dart
|
lib/model/search_asset_response_dto.dart
|
||||||
@@ -400,7 +403,6 @@ lib/model/tone_mapping.dart
|
|||||||
lib/model/transcode_hw_accel.dart
|
lib/model/transcode_hw_accel.dart
|
||||||
lib/model/transcode_policy.dart
|
lib/model/transcode_policy.dart
|
||||||
lib/model/update_album_dto.dart
|
lib/model/update_album_dto.dart
|
||||||
lib/model/update_album_user_dto.dart
|
|
||||||
lib/model/update_asset_dto.dart
|
lib/model/update_asset_dto.dart
|
||||||
lib/model/update_library_dto.dart
|
lib/model/update_library_dto.dart
|
||||||
lib/model/update_partner_dto.dart
|
lib/model/update_partner_dto.dart
|
||||||
@@ -423,11 +425,10 @@ test/activity_create_dto_test.dart
|
|||||||
test/activity_response_dto_test.dart
|
test/activity_response_dto_test.dart
|
||||||
test/activity_statistics_response_dto_test.dart
|
test/activity_statistics_response_dto_test.dart
|
||||||
test/add_users_dto_test.dart
|
test/add_users_dto_test.dart
|
||||||
|
test/admin_onboarding_update_dto_test.dart
|
||||||
test/album_api_test.dart
|
test/album_api_test.dart
|
||||||
test/album_count_response_dto_test.dart
|
test/album_count_response_dto_test.dart
|
||||||
test/album_response_dto_test.dart
|
test/album_response_dto_test.dart
|
||||||
test/album_user_response_dto_test.dart
|
|
||||||
test/album_user_role_test.dart
|
|
||||||
test/all_job_status_response_dto_test.dart
|
test/all_job_status_response_dto_test.dart
|
||||||
test/api_key_api_test.dart
|
test/api_key_api_test.dart
|
||||||
test/api_key_create_dto_test.dart
|
test/api_key_create_dto_test.dart
|
||||||
@@ -486,6 +487,7 @@ test/face_api_test.dart
|
|||||||
test/face_dto_test.dart
|
test/face_dto_test.dart
|
||||||
test/file_checksum_dto_test.dart
|
test/file_checksum_dto_test.dart
|
||||||
test/file_checksum_response_dto_test.dart
|
test/file_checksum_response_dto_test.dart
|
||||||
|
test/file_report_api_test.dart
|
||||||
test/file_report_dto_test.dart
|
test/file_report_dto_test.dart
|
||||||
test/file_report_fix_dto_test.dart
|
test/file_report_fix_dto_test.dart
|
||||||
test/file_report_item_dto_test.dart
|
test/file_report_item_dto_test.dart
|
||||||
@@ -539,6 +541,7 @@ test/queue_status_dto_test.dart
|
|||||||
test/reaction_level_test.dart
|
test/reaction_level_test.dart
|
||||||
test/reaction_type_test.dart
|
test/reaction_type_test.dart
|
||||||
test/recognition_config_test.dart
|
test/recognition_config_test.dart
|
||||||
|
test/reverse_geocoding_state_response_dto_test.dart
|
||||||
test/scan_library_dto_test.dart
|
test/scan_library_dto_test.dart
|
||||||
test/search_album_response_dto_test.dart
|
test/search_album_response_dto_test.dart
|
||||||
test/search_api_test.dart
|
test/search_api_test.dart
|
||||||
@@ -590,6 +593,7 @@ test/system_config_template_storage_option_dto_test.dart
|
|||||||
test/system_config_theme_dto_test.dart
|
test/system_config_theme_dto_test.dart
|
||||||
test/system_config_trash_dto_test.dart
|
test/system_config_trash_dto_test.dart
|
||||||
test/system_config_user_dto_test.dart
|
test/system_config_user_dto_test.dart
|
||||||
|
test/system_metadata_api_test.dart
|
||||||
test/tag_api_test.dart
|
test/tag_api_test.dart
|
||||||
test/tag_response_dto_test.dart
|
test/tag_response_dto_test.dart
|
||||||
test/tag_type_enum_test.dart
|
test/tag_type_enum_test.dart
|
||||||
@@ -602,7 +606,6 @@ test/transcode_hw_accel_test.dart
|
|||||||
test/transcode_policy_test.dart
|
test/transcode_policy_test.dart
|
||||||
test/trash_api_test.dart
|
test/trash_api_test.dart
|
||||||
test/update_album_dto_test.dart
|
test/update_album_dto_test.dart
|
||||||
test/update_album_user_dto_test.dart
|
|
||||||
test/update_asset_dto_test.dart
|
test/update_asset_dto_test.dart
|
||||||
test/update_library_dto_test.dart
|
test/update_library_dto_test.dart
|
||||||
test/update_partner_dto_test.dart
|
test/update_partner_dto_test.dart
|
||||||
|
|||||||
Generated
+9
-9
@@ -3,7 +3,7 @@ Immich API
|
|||||||
|
|
||||||
This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
||||||
|
|
||||||
- API version: 1.101.0
|
- API version: 1.102.3
|
||||||
- Build package: org.openapitools.codegen.languages.DartClientCodegen
|
- Build package: org.openapitools.codegen.languages.DartClientCodegen
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
@@ -91,7 +91,6 @@ Class | Method | HTTP request | Description
|
|||||||
*AlbumApi* | [**removeAssetFromAlbum**](doc//AlbumApi.md#removeassetfromalbum) | **DELETE** /album/{id}/assets |
|
*AlbumApi* | [**removeAssetFromAlbum**](doc//AlbumApi.md#removeassetfromalbum) | **DELETE** /album/{id}/assets |
|
||||||
*AlbumApi* | [**removeUserFromAlbum**](doc//AlbumApi.md#removeuserfromalbum) | **DELETE** /album/{id}/user/{userId} |
|
*AlbumApi* | [**removeUserFromAlbum**](doc//AlbumApi.md#removeuserfromalbum) | **DELETE** /album/{id}/user/{userId} |
|
||||||
*AlbumApi* | [**updateAlbumInfo**](doc//AlbumApi.md#updatealbuminfo) | **PATCH** /album/{id} |
|
*AlbumApi* | [**updateAlbumInfo**](doc//AlbumApi.md#updatealbuminfo) | **PATCH** /album/{id} |
|
||||||
*AlbumApi* | [**updateAlbumUser**](doc//AlbumApi.md#updatealbumuser) | **PUT** /album/{id}/permission/{userId} |
|
|
||||||
*AssetApi* | [**checkBulkUpload**](doc//AssetApi.md#checkbulkupload) | **POST** /asset/bulk-upload-check |
|
*AssetApi* | [**checkBulkUpload**](doc//AssetApi.md#checkbulkupload) | **POST** /asset/bulk-upload-check |
|
||||||
*AssetApi* | [**checkExistingAssets**](doc//AssetApi.md#checkexistingassets) | **POST** /asset/exist |
|
*AssetApi* | [**checkExistingAssets**](doc//AssetApi.md#checkexistingassets) | **POST** /asset/exist |
|
||||||
*AssetApi* | [**deleteAssets**](doc//AssetApi.md#deleteassets) | **DELETE** /asset |
|
*AssetApi* | [**deleteAssets**](doc//AssetApi.md#deleteassets) | **DELETE** /asset |
|
||||||
@@ -113,10 +112,7 @@ Class | Method | HTTP request | Description
|
|||||||
*AssetApi* | [**updateAssets**](doc//AssetApi.md#updateassets) | **PUT** /asset |
|
*AssetApi* | [**updateAssets**](doc//AssetApi.md#updateassets) | **PUT** /asset |
|
||||||
*AssetApi* | [**updateStackParent**](doc//AssetApi.md#updatestackparent) | **PUT** /asset/stack/parent |
|
*AssetApi* | [**updateStackParent**](doc//AssetApi.md#updatestackparent) | **PUT** /asset/stack/parent |
|
||||||
*AssetApi* | [**uploadFile**](doc//AssetApi.md#uploadfile) | **POST** /asset/upload |
|
*AssetApi* | [**uploadFile**](doc//AssetApi.md#uploadfile) | **POST** /asset/upload |
|
||||||
*AuditApi* | [**fixAuditFiles**](doc//AuditApi.md#fixauditfiles) | **POST** /audit/file-report/fix |
|
|
||||||
*AuditApi* | [**getAuditDeletes**](doc//AuditApi.md#getauditdeletes) | **GET** /audit/deletes |
|
*AuditApi* | [**getAuditDeletes**](doc//AuditApi.md#getauditdeletes) | **GET** /audit/deletes |
|
||||||
*AuditApi* | [**getAuditFiles**](doc//AuditApi.md#getauditfiles) | **GET** /audit/file-report |
|
|
||||||
*AuditApi* | [**getFileChecksums**](doc//AuditApi.md#getfilechecksums) | **POST** /audit/file-report/checksum |
|
|
||||||
*AuthenticationApi* | [**changePassword**](doc//AuthenticationApi.md#changepassword) | **POST** /auth/change-password |
|
*AuthenticationApi* | [**changePassword**](doc//AuthenticationApi.md#changepassword) | **POST** /auth/change-password |
|
||||||
*AuthenticationApi* | [**login**](doc//AuthenticationApi.md#login) | **POST** /auth/login |
|
*AuthenticationApi* | [**login**](doc//AuthenticationApi.md#login) | **POST** /auth/login |
|
||||||
*AuthenticationApi* | [**logout**](doc//AuthenticationApi.md#logout) | **POST** /auth/logout |
|
*AuthenticationApi* | [**logout**](doc//AuthenticationApi.md#logout) | **POST** /auth/logout |
|
||||||
@@ -127,6 +123,9 @@ Class | Method | HTTP request | Description
|
|||||||
*DownloadApi* | [**getDownloadInfo**](doc//DownloadApi.md#getdownloadinfo) | **POST** /download/info |
|
*DownloadApi* | [**getDownloadInfo**](doc//DownloadApi.md#getdownloadinfo) | **POST** /download/info |
|
||||||
*FaceApi* | [**getFaces**](doc//FaceApi.md#getfaces) | **GET** /face |
|
*FaceApi* | [**getFaces**](doc//FaceApi.md#getfaces) | **GET** /face |
|
||||||
*FaceApi* | [**reassignFacesById**](doc//FaceApi.md#reassignfacesbyid) | **PUT** /face/{id} |
|
*FaceApi* | [**reassignFacesById**](doc//FaceApi.md#reassignfacesbyid) | **PUT** /face/{id} |
|
||||||
|
*FileReportApi* | [**fixAuditFiles**](doc//FileReportApi.md#fixauditfiles) | **POST** /report/fix |
|
||||||
|
*FileReportApi* | [**getAuditFiles**](doc//FileReportApi.md#getauditfiles) | **GET** /report |
|
||||||
|
*FileReportApi* | [**getFileChecksums**](doc//FileReportApi.md#getfilechecksums) | **POST** /report/checksum |
|
||||||
*JobApi* | [**getAllJobsStatus**](doc//JobApi.md#getalljobsstatus) | **GET** /jobs |
|
*JobApi* | [**getAllJobsStatus**](doc//JobApi.md#getalljobsstatus) | **GET** /jobs |
|
||||||
*JobApi* | [**sendJobCommand**](doc//JobApi.md#sendjobcommand) | **PUT** /jobs/{id} |
|
*JobApi* | [**sendJobCommand**](doc//JobApi.md#sendjobcommand) | **PUT** /jobs/{id} |
|
||||||
*LibraryApi* | [**createLibrary**](doc//LibraryApi.md#createlibrary) | **POST** /library |
|
*LibraryApi* | [**createLibrary**](doc//LibraryApi.md#createlibrary) | **POST** /library |
|
||||||
@@ -180,7 +179,6 @@ Class | Method | HTTP request | Description
|
|||||||
*ServerInfoApi* | [**getSupportedMediaTypes**](doc//ServerInfoApi.md#getsupportedmediatypes) | **GET** /server-info/media-types |
|
*ServerInfoApi* | [**getSupportedMediaTypes**](doc//ServerInfoApi.md#getsupportedmediatypes) | **GET** /server-info/media-types |
|
||||||
*ServerInfoApi* | [**getTheme**](doc//ServerInfoApi.md#gettheme) | **GET** /server-info/theme |
|
*ServerInfoApi* | [**getTheme**](doc//ServerInfoApi.md#gettheme) | **GET** /server-info/theme |
|
||||||
*ServerInfoApi* | [**pingServer**](doc//ServerInfoApi.md#pingserver) | **GET** /server-info/ping |
|
*ServerInfoApi* | [**pingServer**](doc//ServerInfoApi.md#pingserver) | **GET** /server-info/ping |
|
||||||
*ServerInfoApi* | [**setAdminOnboarding**](doc//ServerInfoApi.md#setadminonboarding) | **POST** /server-info/admin-onboarding |
|
|
||||||
*SessionsApi* | [**deleteAllSessions**](doc//SessionsApi.md#deleteallsessions) | **DELETE** /sessions |
|
*SessionsApi* | [**deleteAllSessions**](doc//SessionsApi.md#deleteallsessions) | **DELETE** /sessions |
|
||||||
*SessionsApi* | [**deleteSession**](doc//SessionsApi.md#deletesession) | **DELETE** /sessions/{id} |
|
*SessionsApi* | [**deleteSession**](doc//SessionsApi.md#deletesession) | **DELETE** /sessions/{id} |
|
||||||
*SessionsApi* | [**getSessions**](doc//SessionsApi.md#getsessions) | **GET** /sessions |
|
*SessionsApi* | [**getSessions**](doc//SessionsApi.md#getsessions) | **GET** /sessions |
|
||||||
@@ -199,6 +197,9 @@ Class | Method | HTTP request | Description
|
|||||||
*SystemConfigApi* | [**getMapStyle**](doc//SystemConfigApi.md#getmapstyle) | **GET** /system-config/map/style.json |
|
*SystemConfigApi* | [**getMapStyle**](doc//SystemConfigApi.md#getmapstyle) | **GET** /system-config/map/style.json |
|
||||||
*SystemConfigApi* | [**getStorageTemplateOptions**](doc//SystemConfigApi.md#getstoragetemplateoptions) | **GET** /system-config/storage-template-options |
|
*SystemConfigApi* | [**getStorageTemplateOptions**](doc//SystemConfigApi.md#getstoragetemplateoptions) | **GET** /system-config/storage-template-options |
|
||||||
*SystemConfigApi* | [**updateConfig**](doc//SystemConfigApi.md#updateconfig) | **PUT** /system-config |
|
*SystemConfigApi* | [**updateConfig**](doc//SystemConfigApi.md#updateconfig) | **PUT** /system-config |
|
||||||
|
*SystemMetadataApi* | [**getAdminOnboarding**](doc//SystemMetadataApi.md#getadminonboarding) | **GET** /system-metadata/admin-onboarding |
|
||||||
|
*SystemMetadataApi* | [**getReverseGeocodingState**](doc//SystemMetadataApi.md#getreversegeocodingstate) | **GET** /system-metadata/reverse-geocoding-state |
|
||||||
|
*SystemMetadataApi* | [**updateAdminOnboarding**](doc//SystemMetadataApi.md#updateadminonboarding) | **POST** /system-metadata/admin-onboarding |
|
||||||
*TagApi* | [**createTag**](doc//TagApi.md#createtag) | **POST** /tag |
|
*TagApi* | [**createTag**](doc//TagApi.md#createtag) | **POST** /tag |
|
||||||
*TagApi* | [**deleteTag**](doc//TagApi.md#deletetag) | **DELETE** /tag/{id} |
|
*TagApi* | [**deleteTag**](doc//TagApi.md#deletetag) | **DELETE** /tag/{id} |
|
||||||
*TagApi* | [**getAllTags**](doc//TagApi.md#getalltags) | **GET** /tag |
|
*TagApi* | [**getAllTags**](doc//TagApi.md#getalltags) | **GET** /tag |
|
||||||
@@ -234,10 +235,9 @@ Class | Method | HTTP request | Description
|
|||||||
- [ActivityResponseDto](doc//ActivityResponseDto.md)
|
- [ActivityResponseDto](doc//ActivityResponseDto.md)
|
||||||
- [ActivityStatisticsResponseDto](doc//ActivityStatisticsResponseDto.md)
|
- [ActivityStatisticsResponseDto](doc//ActivityStatisticsResponseDto.md)
|
||||||
- [AddUsersDto](doc//AddUsersDto.md)
|
- [AddUsersDto](doc//AddUsersDto.md)
|
||||||
|
- [AdminOnboardingUpdateDto](doc//AdminOnboardingUpdateDto.md)
|
||||||
- [AlbumCountResponseDto](doc//AlbumCountResponseDto.md)
|
- [AlbumCountResponseDto](doc//AlbumCountResponseDto.md)
|
||||||
- [AlbumResponseDto](doc//AlbumResponseDto.md)
|
- [AlbumResponseDto](doc//AlbumResponseDto.md)
|
||||||
- [AlbumUserResponseDto](doc//AlbumUserResponseDto.md)
|
|
||||||
- [AlbumUserRole](doc//AlbumUserRole.md)
|
|
||||||
- [AllJobStatusResponseDto](doc//AllJobStatusResponseDto.md)
|
- [AllJobStatusResponseDto](doc//AllJobStatusResponseDto.md)
|
||||||
- [AssetBulkDeleteDto](doc//AssetBulkDeleteDto.md)
|
- [AssetBulkDeleteDto](doc//AssetBulkDeleteDto.md)
|
||||||
- [AssetBulkUpdateDto](doc//AssetBulkUpdateDto.md)
|
- [AssetBulkUpdateDto](doc//AssetBulkUpdateDto.md)
|
||||||
@@ -333,6 +333,7 @@ Class | Method | HTTP request | Description
|
|||||||
- [ReactionLevel](doc//ReactionLevel.md)
|
- [ReactionLevel](doc//ReactionLevel.md)
|
||||||
- [ReactionType](doc//ReactionType.md)
|
- [ReactionType](doc//ReactionType.md)
|
||||||
- [RecognitionConfig](doc//RecognitionConfig.md)
|
- [RecognitionConfig](doc//RecognitionConfig.md)
|
||||||
|
- [ReverseGeocodingStateResponseDto](doc//ReverseGeocodingStateResponseDto.md)
|
||||||
- [ScanLibraryDto](doc//ScanLibraryDto.md)
|
- [ScanLibraryDto](doc//ScanLibraryDto.md)
|
||||||
- [SearchAlbumResponseDto](doc//SearchAlbumResponseDto.md)
|
- [SearchAlbumResponseDto](doc//SearchAlbumResponseDto.md)
|
||||||
- [SearchAssetResponseDto](doc//SearchAssetResponseDto.md)
|
- [SearchAssetResponseDto](doc//SearchAssetResponseDto.md)
|
||||||
@@ -387,7 +388,6 @@ Class | Method | HTTP request | Description
|
|||||||
- [TranscodeHWAccel](doc//TranscodeHWAccel.md)
|
- [TranscodeHWAccel](doc//TranscodeHWAccel.md)
|
||||||
- [TranscodePolicy](doc//TranscodePolicy.md)
|
- [TranscodePolicy](doc//TranscodePolicy.md)
|
||||||
- [UpdateAlbumDto](doc//UpdateAlbumDto.md)
|
- [UpdateAlbumDto](doc//UpdateAlbumDto.md)
|
||||||
- [UpdateAlbumUserDto](doc//UpdateAlbumUserDto.md)
|
|
||||||
- [UpdateAssetDto](doc//UpdateAssetDto.md)
|
- [UpdateAssetDto](doc//UpdateAssetDto.md)
|
||||||
- [UpdateLibraryDto](doc//UpdateLibraryDto.md)
|
- [UpdateLibraryDto](doc//UpdateLibraryDto.md)
|
||||||
- [UpdatePartnerDto](doc//UpdatePartnerDto.md)
|
- [UpdatePartnerDto](doc//UpdatePartnerDto.md)
|
||||||
|
|||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
# openapi.model.AdminOnboardingUpdateDto
|
||||||
|
|
||||||
|
## Load the model package
|
||||||
|
```dart
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
Name | Type | Description | Notes
|
||||||
|
------------ | ------------- | ------------- | -------------
|
||||||
|
**isOnboarded** | **bool** | |
|
||||||
|
|
||||||
|
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
|
||||||
Generated
-163
@@ -9,66 +9,9 @@ All URIs are relative to */api*
|
|||||||
|
|
||||||
Method | HTTP request | Description
|
Method | HTTP request | Description
|
||||||
------------- | ------------- | -------------
|
------------- | ------------- | -------------
|
||||||
[**fixAuditFiles**](AuditApi.md#fixauditfiles) | **POST** /audit/file-report/fix |
|
|
||||||
[**getAuditDeletes**](AuditApi.md#getauditdeletes) | **GET** /audit/deletes |
|
[**getAuditDeletes**](AuditApi.md#getauditdeletes) | **GET** /audit/deletes |
|
||||||
[**getAuditFiles**](AuditApi.md#getauditfiles) | **GET** /audit/file-report |
|
|
||||||
[**getFileChecksums**](AuditApi.md#getfilechecksums) | **POST** /audit/file-report/checksum |
|
|
||||||
|
|
||||||
|
|
||||||
# **fixAuditFiles**
|
|
||||||
> fixAuditFiles(fileReportFixDto)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Example
|
|
||||||
```dart
|
|
||||||
import 'package:openapi/api.dart';
|
|
||||||
// TODO Configure API key authorization: cookie
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKey = 'YOUR_API_KEY';
|
|
||||||
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKeyPrefix = 'Bearer';
|
|
||||||
// TODO Configure API key authorization: api_key
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKey = 'YOUR_API_KEY';
|
|
||||||
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKeyPrefix = 'Bearer';
|
|
||||||
// TODO Configure HTTP Bearer authorization: bearer
|
|
||||||
// Case 1. Use String Token
|
|
||||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken('YOUR_ACCESS_TOKEN');
|
|
||||||
// Case 2. Use Function which generate token.
|
|
||||||
// String yourTokenGeneratorFunction() { ... }
|
|
||||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
|
|
||||||
|
|
||||||
final api_instance = AuditApi();
|
|
||||||
final fileReportFixDto = FileReportFixDto(); // FileReportFixDto |
|
|
||||||
|
|
||||||
try {
|
|
||||||
api_instance.fixAuditFiles(fileReportFixDto);
|
|
||||||
} catch (e) {
|
|
||||||
print('Exception when calling AuditApi->fixAuditFiles: $e\n');
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------- | ------------- | ------------- | -------------
|
|
||||||
**fileReportFixDto** | [**FileReportFixDto**](FileReportFixDto.md)| |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
void (empty response body)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer)
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: application/json
|
|
||||||
- **Accept**: Not defined
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
# **getAuditDeletes**
|
# **getAuditDeletes**
|
||||||
> AuditDeletesResponseDto getAuditDeletes(after, entityType, userId)
|
> AuditDeletesResponseDto getAuditDeletes(after, entityType, userId)
|
||||||
|
|
||||||
@@ -128,109 +71,3 @@ Name | Type | Description | Notes
|
|||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||||
|
|
||||||
# **getAuditFiles**
|
|
||||||
> FileReportDto getAuditFiles()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Example
|
|
||||||
```dart
|
|
||||||
import 'package:openapi/api.dart';
|
|
||||||
// TODO Configure API key authorization: cookie
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKey = 'YOUR_API_KEY';
|
|
||||||
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKeyPrefix = 'Bearer';
|
|
||||||
// TODO Configure API key authorization: api_key
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKey = 'YOUR_API_KEY';
|
|
||||||
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKeyPrefix = 'Bearer';
|
|
||||||
// TODO Configure HTTP Bearer authorization: bearer
|
|
||||||
// Case 1. Use String Token
|
|
||||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken('YOUR_ACCESS_TOKEN');
|
|
||||||
// Case 2. Use Function which generate token.
|
|
||||||
// String yourTokenGeneratorFunction() { ... }
|
|
||||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
|
|
||||||
|
|
||||||
final api_instance = AuditApi();
|
|
||||||
|
|
||||||
try {
|
|
||||||
final result = api_instance.getAuditFiles();
|
|
||||||
print(result);
|
|
||||||
} catch (e) {
|
|
||||||
print('Exception when calling AuditApi->getAuditFiles: $e\n');
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
This endpoint does not need any parameter.
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**FileReportDto**](FileReportDto.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer)
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: Not defined
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
# **getFileChecksums**
|
|
||||||
> List<FileChecksumResponseDto> getFileChecksums(fileChecksumDto)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Example
|
|
||||||
```dart
|
|
||||||
import 'package:openapi/api.dart';
|
|
||||||
// TODO Configure API key authorization: cookie
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKey = 'YOUR_API_KEY';
|
|
||||||
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKeyPrefix = 'Bearer';
|
|
||||||
// TODO Configure API key authorization: api_key
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKey = 'YOUR_API_KEY';
|
|
||||||
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKeyPrefix = 'Bearer';
|
|
||||||
// TODO Configure HTTP Bearer authorization: bearer
|
|
||||||
// Case 1. Use String Token
|
|
||||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken('YOUR_ACCESS_TOKEN');
|
|
||||||
// Case 2. Use Function which generate token.
|
|
||||||
// String yourTokenGeneratorFunction() { ... }
|
|
||||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
|
|
||||||
|
|
||||||
final api_instance = AuditApi();
|
|
||||||
final fileChecksumDto = FileChecksumDto(); // FileChecksumDto |
|
|
||||||
|
|
||||||
try {
|
|
||||||
final result = api_instance.getFileChecksums(fileChecksumDto);
|
|
||||||
print(result);
|
|
||||||
} catch (e) {
|
|
||||||
print('Exception when calling AuditApi->getFileChecksums: $e\n');
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------- | ------------- | ------------- | -------------
|
|
||||||
**fileChecksumDto** | [**FileChecksumDto**](FileChecksumDto.md)| |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**List<FileChecksumResponseDto>**](FileChecksumResponseDto.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer)
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: application/json
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|||||||
Generated
+176
@@ -0,0 +1,176 @@
|
|||||||
|
# openapi.api.FileReportApi
|
||||||
|
|
||||||
|
## Load the API package
|
||||||
|
```dart
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
```
|
||||||
|
|
||||||
|
All URIs are relative to */api*
|
||||||
|
|
||||||
|
Method | HTTP request | Description
|
||||||
|
------------- | ------------- | -------------
|
||||||
|
[**fixAuditFiles**](FileReportApi.md#fixauditfiles) | **POST** /report/fix |
|
||||||
|
[**getAuditFiles**](FileReportApi.md#getauditfiles) | **GET** /report |
|
||||||
|
[**getFileChecksums**](FileReportApi.md#getfilechecksums) | **POST** /report/checksum |
|
||||||
|
|
||||||
|
|
||||||
|
# **fixAuditFiles**
|
||||||
|
> fixAuditFiles(fileReportFixDto)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Example
|
||||||
|
```dart
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
// TODO Configure API key authorization: cookie
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKey = 'YOUR_API_KEY';
|
||||||
|
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKeyPrefix = 'Bearer';
|
||||||
|
// TODO Configure API key authorization: api_key
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKey = 'YOUR_API_KEY';
|
||||||
|
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKeyPrefix = 'Bearer';
|
||||||
|
// TODO Configure HTTP Bearer authorization: bearer
|
||||||
|
// Case 1. Use String Token
|
||||||
|
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken('YOUR_ACCESS_TOKEN');
|
||||||
|
// Case 2. Use Function which generate token.
|
||||||
|
// String yourTokenGeneratorFunction() { ... }
|
||||||
|
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
|
||||||
|
|
||||||
|
final api_instance = FileReportApi();
|
||||||
|
final fileReportFixDto = FileReportFixDto(); // FileReportFixDto |
|
||||||
|
|
||||||
|
try {
|
||||||
|
api_instance.fixAuditFiles(fileReportFixDto);
|
||||||
|
} catch (e) {
|
||||||
|
print('Exception when calling FileReportApi->fixAuditFiles: $e\n');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
Name | Type | Description | Notes
|
||||||
|
------------- | ------------- | ------------- | -------------
|
||||||
|
**fileReportFixDto** | [**FileReportFixDto**](FileReportFixDto.md)| |
|
||||||
|
|
||||||
|
### Return type
|
||||||
|
|
||||||
|
void (empty response body)
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer)
|
||||||
|
|
||||||
|
### HTTP request headers
|
||||||
|
|
||||||
|
- **Content-Type**: application/json
|
||||||
|
- **Accept**: Not defined
|
||||||
|
|
||||||
|
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
# **getAuditFiles**
|
||||||
|
> FileReportDto getAuditFiles()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Example
|
||||||
|
```dart
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
// TODO Configure API key authorization: cookie
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKey = 'YOUR_API_KEY';
|
||||||
|
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKeyPrefix = 'Bearer';
|
||||||
|
// TODO Configure API key authorization: api_key
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKey = 'YOUR_API_KEY';
|
||||||
|
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKeyPrefix = 'Bearer';
|
||||||
|
// TODO Configure HTTP Bearer authorization: bearer
|
||||||
|
// Case 1. Use String Token
|
||||||
|
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken('YOUR_ACCESS_TOKEN');
|
||||||
|
// Case 2. Use Function which generate token.
|
||||||
|
// String yourTokenGeneratorFunction() { ... }
|
||||||
|
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
|
||||||
|
|
||||||
|
final api_instance = FileReportApi();
|
||||||
|
|
||||||
|
try {
|
||||||
|
final result = api_instance.getAuditFiles();
|
||||||
|
print(result);
|
||||||
|
} catch (e) {
|
||||||
|
print('Exception when calling FileReportApi->getAuditFiles: $e\n');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
This endpoint does not need any parameter.
|
||||||
|
|
||||||
|
### Return type
|
||||||
|
|
||||||
|
[**FileReportDto**](FileReportDto.md)
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer)
|
||||||
|
|
||||||
|
### HTTP request headers
|
||||||
|
|
||||||
|
- **Content-Type**: Not defined
|
||||||
|
- **Accept**: application/json
|
||||||
|
|
||||||
|
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
# **getFileChecksums**
|
||||||
|
> List<FileChecksumResponseDto> getFileChecksums(fileChecksumDto)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Example
|
||||||
|
```dart
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
// TODO Configure API key authorization: cookie
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKey = 'YOUR_API_KEY';
|
||||||
|
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKeyPrefix = 'Bearer';
|
||||||
|
// TODO Configure API key authorization: api_key
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKey = 'YOUR_API_KEY';
|
||||||
|
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKeyPrefix = 'Bearer';
|
||||||
|
// TODO Configure HTTP Bearer authorization: bearer
|
||||||
|
// Case 1. Use String Token
|
||||||
|
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken('YOUR_ACCESS_TOKEN');
|
||||||
|
// Case 2. Use Function which generate token.
|
||||||
|
// String yourTokenGeneratorFunction() { ... }
|
||||||
|
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
|
||||||
|
|
||||||
|
final api_instance = FileReportApi();
|
||||||
|
final fileChecksumDto = FileChecksumDto(); // FileChecksumDto |
|
||||||
|
|
||||||
|
try {
|
||||||
|
final result = api_instance.getFileChecksums(fileChecksumDto);
|
||||||
|
print(result);
|
||||||
|
} catch (e) {
|
||||||
|
print('Exception when calling FileReportApi->getFileChecksums: $e\n');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
Name | Type | Description | Notes
|
||||||
|
------------- | ------------- | ------------- | -------------
|
||||||
|
**fileChecksumDto** | [**FileChecksumDto**](FileChecksumDto.md)| |
|
||||||
|
|
||||||
|
### Return type
|
||||||
|
|
||||||
|
[**List<FileChecksumResponseDto>**](FileChecksumResponseDto.md)
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer)
|
||||||
|
|
||||||
|
### HTTP request headers
|
||||||
|
|
||||||
|
- **Content-Type**: application/json
|
||||||
|
- **Accept**: application/json
|
||||||
|
|
||||||
|
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# openapi.model.ReverseGeocodingStateResponseDto
|
||||||
|
|
||||||
|
## Load the model package
|
||||||
|
```dart
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
Name | Type | Description | Notes
|
||||||
|
------------ | ------------- | ------------- | -------------
|
||||||
|
**lastImportFileName** | **String** | |
|
||||||
|
**lastUpdate** | **String** | |
|
||||||
|
|
||||||
|
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
|
||||||
Generated
-51
@@ -17,7 +17,6 @@ Method | HTTP request | Description
|
|||||||
[**getSupportedMediaTypes**](ServerInfoApi.md#getsupportedmediatypes) | **GET** /server-info/media-types |
|
[**getSupportedMediaTypes**](ServerInfoApi.md#getsupportedmediatypes) | **GET** /server-info/media-types |
|
||||||
[**getTheme**](ServerInfoApi.md#gettheme) | **GET** /server-info/theme |
|
[**getTheme**](ServerInfoApi.md#gettheme) | **GET** /server-info/theme |
|
||||||
[**pingServer**](ServerInfoApi.md#pingserver) | **GET** /server-info/ping |
|
[**pingServer**](ServerInfoApi.md#pingserver) | **GET** /server-info/ping |
|
||||||
[**setAdminOnboarding**](ServerInfoApi.md#setadminonboarding) | **POST** /server-info/admin-onboarding |
|
|
||||||
|
|
||||||
|
|
||||||
# **getServerConfig**
|
# **getServerConfig**
|
||||||
@@ -344,53 +343,3 @@ No authorization required
|
|||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||||
|
|
||||||
# **setAdminOnboarding**
|
|
||||||
> setAdminOnboarding()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Example
|
|
||||||
```dart
|
|
||||||
import 'package:openapi/api.dart';
|
|
||||||
// TODO Configure API key authorization: cookie
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKey = 'YOUR_API_KEY';
|
|
||||||
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKeyPrefix = 'Bearer';
|
|
||||||
// TODO Configure API key authorization: api_key
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKey = 'YOUR_API_KEY';
|
|
||||||
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
|
||||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKeyPrefix = 'Bearer';
|
|
||||||
// TODO Configure HTTP Bearer authorization: bearer
|
|
||||||
// Case 1. Use String Token
|
|
||||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken('YOUR_ACCESS_TOKEN');
|
|
||||||
// Case 2. Use Function which generate token.
|
|
||||||
// String yourTokenGeneratorFunction() { ... }
|
|
||||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
|
|
||||||
|
|
||||||
final api_instance = ServerInfoApi();
|
|
||||||
|
|
||||||
try {
|
|
||||||
api_instance.setAdminOnboarding();
|
|
||||||
} catch (e) {
|
|
||||||
print('Exception when calling ServerInfoApi->setAdminOnboarding: $e\n');
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
This endpoint does not need any parameter.
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
void (empty response body)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer)
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: Not defined
|
|
||||||
- **Accept**: Not defined
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|||||||
+1
@@ -9,6 +9,7 @@ import 'package:openapi/api.dart';
|
|||||||
Name | Type | Description | Notes
|
Name | Type | Description | Notes
|
||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**colorspace** | [**Colorspace**](Colorspace.md) | |
|
**colorspace** | [**Colorspace**](Colorspace.md) | |
|
||||||
|
**extractEmbedded** | **bool** | |
|
||||||
**previewFormat** | [**ImageFormat**](ImageFormat.md) | |
|
**previewFormat** | [**ImageFormat**](ImageFormat.md) | |
|
||||||
**previewSize** | **int** | |
|
**previewSize** | **int** | |
|
||||||
**quality** | **int** | |
|
**quality** | **int** | |
|
||||||
|
|||||||
Generated
+172
@@ -0,0 +1,172 @@
|
|||||||
|
# openapi.api.SystemMetadataApi
|
||||||
|
|
||||||
|
## Load the API package
|
||||||
|
```dart
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
```
|
||||||
|
|
||||||
|
All URIs are relative to */api*
|
||||||
|
|
||||||
|
Method | HTTP request | Description
|
||||||
|
------------- | ------------- | -------------
|
||||||
|
[**getAdminOnboarding**](SystemMetadataApi.md#getadminonboarding) | **GET** /system-metadata/admin-onboarding |
|
||||||
|
[**getReverseGeocodingState**](SystemMetadataApi.md#getreversegeocodingstate) | **GET** /system-metadata/reverse-geocoding-state |
|
||||||
|
[**updateAdminOnboarding**](SystemMetadataApi.md#updateadminonboarding) | **POST** /system-metadata/admin-onboarding |
|
||||||
|
|
||||||
|
|
||||||
|
# **getAdminOnboarding**
|
||||||
|
> AdminOnboardingUpdateDto getAdminOnboarding()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Example
|
||||||
|
```dart
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
// TODO Configure API key authorization: cookie
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKey = 'YOUR_API_KEY';
|
||||||
|
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKeyPrefix = 'Bearer';
|
||||||
|
// TODO Configure API key authorization: api_key
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKey = 'YOUR_API_KEY';
|
||||||
|
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKeyPrefix = 'Bearer';
|
||||||
|
// TODO Configure HTTP Bearer authorization: bearer
|
||||||
|
// Case 1. Use String Token
|
||||||
|
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken('YOUR_ACCESS_TOKEN');
|
||||||
|
// Case 2. Use Function which generate token.
|
||||||
|
// String yourTokenGeneratorFunction() { ... }
|
||||||
|
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
|
||||||
|
|
||||||
|
final api_instance = SystemMetadataApi();
|
||||||
|
|
||||||
|
try {
|
||||||
|
final result = api_instance.getAdminOnboarding();
|
||||||
|
print(result);
|
||||||
|
} catch (e) {
|
||||||
|
print('Exception when calling SystemMetadataApi->getAdminOnboarding: $e\n');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
This endpoint does not need any parameter.
|
||||||
|
|
||||||
|
### Return type
|
||||||
|
|
||||||
|
[**AdminOnboardingUpdateDto**](AdminOnboardingUpdateDto.md)
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer)
|
||||||
|
|
||||||
|
### HTTP request headers
|
||||||
|
|
||||||
|
- **Content-Type**: Not defined
|
||||||
|
- **Accept**: application/json
|
||||||
|
|
||||||
|
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
# **getReverseGeocodingState**
|
||||||
|
> ReverseGeocodingStateResponseDto getReverseGeocodingState()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Example
|
||||||
|
```dart
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
// TODO Configure API key authorization: cookie
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKey = 'YOUR_API_KEY';
|
||||||
|
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKeyPrefix = 'Bearer';
|
||||||
|
// TODO Configure API key authorization: api_key
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKey = 'YOUR_API_KEY';
|
||||||
|
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKeyPrefix = 'Bearer';
|
||||||
|
// TODO Configure HTTP Bearer authorization: bearer
|
||||||
|
// Case 1. Use String Token
|
||||||
|
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken('YOUR_ACCESS_TOKEN');
|
||||||
|
// Case 2. Use Function which generate token.
|
||||||
|
// String yourTokenGeneratorFunction() { ... }
|
||||||
|
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
|
||||||
|
|
||||||
|
final api_instance = SystemMetadataApi();
|
||||||
|
|
||||||
|
try {
|
||||||
|
final result = api_instance.getReverseGeocodingState();
|
||||||
|
print(result);
|
||||||
|
} catch (e) {
|
||||||
|
print('Exception when calling SystemMetadataApi->getReverseGeocodingState: $e\n');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
This endpoint does not need any parameter.
|
||||||
|
|
||||||
|
### Return type
|
||||||
|
|
||||||
|
[**ReverseGeocodingStateResponseDto**](ReverseGeocodingStateResponseDto.md)
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer)
|
||||||
|
|
||||||
|
### HTTP request headers
|
||||||
|
|
||||||
|
- **Content-Type**: Not defined
|
||||||
|
- **Accept**: application/json
|
||||||
|
|
||||||
|
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
# **updateAdminOnboarding**
|
||||||
|
> updateAdminOnboarding(adminOnboardingUpdateDto)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Example
|
||||||
|
```dart
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
// TODO Configure API key authorization: cookie
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKey = 'YOUR_API_KEY';
|
||||||
|
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKeyPrefix = 'Bearer';
|
||||||
|
// TODO Configure API key authorization: api_key
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKey = 'YOUR_API_KEY';
|
||||||
|
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||||
|
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKeyPrefix = 'Bearer';
|
||||||
|
// TODO Configure HTTP Bearer authorization: bearer
|
||||||
|
// Case 1. Use String Token
|
||||||
|
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken('YOUR_ACCESS_TOKEN');
|
||||||
|
// Case 2. Use Function which generate token.
|
||||||
|
// String yourTokenGeneratorFunction() { ... }
|
||||||
|
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
|
||||||
|
|
||||||
|
final api_instance = SystemMetadataApi();
|
||||||
|
final adminOnboardingUpdateDto = AdminOnboardingUpdateDto(); // AdminOnboardingUpdateDto |
|
||||||
|
|
||||||
|
try {
|
||||||
|
api_instance.updateAdminOnboarding(adminOnboardingUpdateDto);
|
||||||
|
} catch (e) {
|
||||||
|
print('Exception when calling SystemMetadataApi->updateAdminOnboarding: $e\n');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
Name | Type | Description | Notes
|
||||||
|
------------- | ------------- | ------------- | -------------
|
||||||
|
**adminOnboardingUpdateDto** | [**AdminOnboardingUpdateDto**](AdminOnboardingUpdateDto.md)| |
|
||||||
|
|
||||||
|
### Return type
|
||||||
|
|
||||||
|
void (empty response body)
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer)
|
||||||
|
|
||||||
|
### HTTP request headers
|
||||||
|
|
||||||
|
- **Content-Type**: application/json
|
||||||
|
- **Accept**: Not defined
|
||||||
|
|
||||||
|
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||||
|
|
||||||
Generated
+4
@@ -37,6 +37,7 @@ part 'api/audit_api.dart';
|
|||||||
part 'api/authentication_api.dart';
|
part 'api/authentication_api.dart';
|
||||||
part 'api/download_api.dart';
|
part 'api/download_api.dart';
|
||||||
part 'api/face_api.dart';
|
part 'api/face_api.dart';
|
||||||
|
part 'api/file_report_api.dart';
|
||||||
part 'api/job_api.dart';
|
part 'api/job_api.dart';
|
||||||
part 'api/library_api.dart';
|
part 'api/library_api.dart';
|
||||||
part 'api/memory_api.dart';
|
part 'api/memory_api.dart';
|
||||||
@@ -49,6 +50,7 @@ part 'api/sessions_api.dart';
|
|||||||
part 'api/shared_link_api.dart';
|
part 'api/shared_link_api.dart';
|
||||||
part 'api/sync_api.dart';
|
part 'api/sync_api.dart';
|
||||||
part 'api/system_config_api.dart';
|
part 'api/system_config_api.dart';
|
||||||
|
part 'api/system_metadata_api.dart';
|
||||||
part 'api/tag_api.dart';
|
part 'api/tag_api.dart';
|
||||||
part 'api/timeline_api.dart';
|
part 'api/timeline_api.dart';
|
||||||
part 'api/trash_api.dart';
|
part 'api/trash_api.dart';
|
||||||
@@ -62,6 +64,7 @@ part 'model/activity_create_dto.dart';
|
|||||||
part 'model/activity_response_dto.dart';
|
part 'model/activity_response_dto.dart';
|
||||||
part 'model/activity_statistics_response_dto.dart';
|
part 'model/activity_statistics_response_dto.dart';
|
||||||
part 'model/add_users_dto.dart';
|
part 'model/add_users_dto.dart';
|
||||||
|
part 'model/admin_onboarding_update_dto.dart';
|
||||||
part 'model/album_count_response_dto.dart';
|
part 'model/album_count_response_dto.dart';
|
||||||
part 'model/album_response_dto.dart';
|
part 'model/album_response_dto.dart';
|
||||||
part 'model/album_user_response_dto.dart';
|
part 'model/album_user_response_dto.dart';
|
||||||
@@ -161,6 +164,7 @@ part 'model/queue_status_dto.dart';
|
|||||||
part 'model/reaction_level.dart';
|
part 'model/reaction_level.dart';
|
||||||
part 'model/reaction_type.dart';
|
part 'model/reaction_type.dart';
|
||||||
part 'model/recognition_config.dart';
|
part 'model/recognition_config.dart';
|
||||||
|
part 'model/reverse_geocoding_state_response_dto.dart';
|
||||||
part 'model/scan_library_dto.dart';
|
part 'model/scan_library_dto.dart';
|
||||||
part 'model/search_album_response_dto.dart';
|
part 'model/search_album_response_dto.dart';
|
||||||
part 'model/search_asset_response_dto.dart';
|
part 'model/search_asset_response_dto.dart';
|
||||||
|
|||||||
Generated
-130
@@ -16,45 +16,6 @@ class AuditApi {
|
|||||||
|
|
||||||
final ApiClient apiClient;
|
final ApiClient apiClient;
|
||||||
|
|
||||||
/// Performs an HTTP 'POST /audit/file-report/fix' operation and returns the [Response].
|
|
||||||
/// Parameters:
|
|
||||||
///
|
|
||||||
/// * [FileReportFixDto] fileReportFixDto (required):
|
|
||||||
Future<Response> fixAuditFilesWithHttpInfo(FileReportFixDto fileReportFixDto,) async {
|
|
||||||
// ignore: prefer_const_declarations
|
|
||||||
final path = r'/audit/file-report/fix';
|
|
||||||
|
|
||||||
// ignore: prefer_final_locals
|
|
||||||
Object? postBody = fileReportFixDto;
|
|
||||||
|
|
||||||
final queryParams = <QueryParam>[];
|
|
||||||
final headerParams = <String, String>{};
|
|
||||||
final formParams = <String, String>{};
|
|
||||||
|
|
||||||
const contentTypes = <String>['application/json'];
|
|
||||||
|
|
||||||
|
|
||||||
return apiClient.invokeAPI(
|
|
||||||
path,
|
|
||||||
'POST',
|
|
||||||
queryParams,
|
|
||||||
postBody,
|
|
||||||
headerParams,
|
|
||||||
formParams,
|
|
||||||
contentTypes.isEmpty ? null : contentTypes.first,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parameters:
|
|
||||||
///
|
|
||||||
/// * [FileReportFixDto] fileReportFixDto (required):
|
|
||||||
Future<void> fixAuditFiles(FileReportFixDto fileReportFixDto,) async {
|
|
||||||
final response = await fixAuditFilesWithHttpInfo(fileReportFixDto,);
|
|
||||||
if (response.statusCode >= HttpStatus.badRequest) {
|
|
||||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Performs an HTTP 'GET /audit/deletes' operation and returns the [Response].
|
/// Performs an HTTP 'GET /audit/deletes' operation and returns the [Response].
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
@@ -115,95 +76,4 @@ class AuditApi {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Performs an HTTP 'GET /audit/file-report' operation and returns the [Response].
|
|
||||||
Future<Response> getAuditFilesWithHttpInfo() async {
|
|
||||||
// ignore: prefer_const_declarations
|
|
||||||
final path = r'/audit/file-report';
|
|
||||||
|
|
||||||
// ignore: prefer_final_locals
|
|
||||||
Object? postBody;
|
|
||||||
|
|
||||||
final queryParams = <QueryParam>[];
|
|
||||||
final headerParams = <String, String>{};
|
|
||||||
final formParams = <String, String>{};
|
|
||||||
|
|
||||||
const contentTypes = <String>[];
|
|
||||||
|
|
||||||
|
|
||||||
return apiClient.invokeAPI(
|
|
||||||
path,
|
|
||||||
'GET',
|
|
||||||
queryParams,
|
|
||||||
postBody,
|
|
||||||
headerParams,
|
|
||||||
formParams,
|
|
||||||
contentTypes.isEmpty ? null : contentTypes.first,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<FileReportDto?> getAuditFiles() async {
|
|
||||||
final response = await getAuditFilesWithHttpInfo();
|
|
||||||
if (response.statusCode >= HttpStatus.badRequest) {
|
|
||||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
|
||||||
}
|
|
||||||
// When a remote server returns no body with a status of 204, we shall not decode it.
|
|
||||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
|
||||||
// FormatException when trying to decode an empty string.
|
|
||||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
|
||||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'FileReportDto',) as FileReportDto;
|
|
||||||
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Performs an HTTP 'POST /audit/file-report/checksum' operation and returns the [Response].
|
|
||||||
/// Parameters:
|
|
||||||
///
|
|
||||||
/// * [FileChecksumDto] fileChecksumDto (required):
|
|
||||||
Future<Response> getFileChecksumsWithHttpInfo(FileChecksumDto fileChecksumDto,) async {
|
|
||||||
// ignore: prefer_const_declarations
|
|
||||||
final path = r'/audit/file-report/checksum';
|
|
||||||
|
|
||||||
// ignore: prefer_final_locals
|
|
||||||
Object? postBody = fileChecksumDto;
|
|
||||||
|
|
||||||
final queryParams = <QueryParam>[];
|
|
||||||
final headerParams = <String, String>{};
|
|
||||||
final formParams = <String, String>{};
|
|
||||||
|
|
||||||
const contentTypes = <String>['application/json'];
|
|
||||||
|
|
||||||
|
|
||||||
return apiClient.invokeAPI(
|
|
||||||
path,
|
|
||||||
'POST',
|
|
||||||
queryParams,
|
|
||||||
postBody,
|
|
||||||
headerParams,
|
|
||||||
formParams,
|
|
||||||
contentTypes.isEmpty ? null : contentTypes.first,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parameters:
|
|
||||||
///
|
|
||||||
/// * [FileChecksumDto] fileChecksumDto (required):
|
|
||||||
Future<List<FileChecksumResponseDto>?> getFileChecksums(FileChecksumDto fileChecksumDto,) async {
|
|
||||||
final response = await getFileChecksumsWithHttpInfo(fileChecksumDto,);
|
|
||||||
if (response.statusCode >= HttpStatus.badRequest) {
|
|
||||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
|
||||||
}
|
|
||||||
// When a remote server returns no body with a status of 204, we shall not decode it.
|
|
||||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
|
||||||
// FormatException when trying to decode an empty string.
|
|
||||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
|
||||||
final responseBody = await _decodeBodyBytes(response);
|
|
||||||
return (await apiClient.deserializeAsync(responseBody, 'List<FileChecksumResponseDto>') as List)
|
|
||||||
.cast<FileChecksumResponseDto>()
|
|
||||||
.toList(growable: false);
|
|
||||||
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+148
@@ -0,0 +1,148 @@
|
|||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
part of openapi.api;
|
||||||
|
|
||||||
|
|
||||||
|
class FileReportApi {
|
||||||
|
FileReportApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient;
|
||||||
|
|
||||||
|
final ApiClient apiClient;
|
||||||
|
|
||||||
|
/// Performs an HTTP 'POST /report/fix' operation and returns the [Response].
|
||||||
|
/// Parameters:
|
||||||
|
///
|
||||||
|
/// * [FileReportFixDto] fileReportFixDto (required):
|
||||||
|
Future<Response> fixAuditFilesWithHttpInfo(FileReportFixDto fileReportFixDto,) async {
|
||||||
|
// ignore: prefer_const_declarations
|
||||||
|
final path = r'/report/fix';
|
||||||
|
|
||||||
|
// ignore: prefer_final_locals
|
||||||
|
Object? postBody = fileReportFixDto;
|
||||||
|
|
||||||
|
final queryParams = <QueryParam>[];
|
||||||
|
final headerParams = <String, String>{};
|
||||||
|
final formParams = <String, String>{};
|
||||||
|
|
||||||
|
const contentTypes = <String>['application/json'];
|
||||||
|
|
||||||
|
|
||||||
|
return apiClient.invokeAPI(
|
||||||
|
path,
|
||||||
|
'POST',
|
||||||
|
queryParams,
|
||||||
|
postBody,
|
||||||
|
headerParams,
|
||||||
|
formParams,
|
||||||
|
contentTypes.isEmpty ? null : contentTypes.first,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parameters:
|
||||||
|
///
|
||||||
|
/// * [FileReportFixDto] fileReportFixDto (required):
|
||||||
|
Future<void> fixAuditFiles(FileReportFixDto fileReportFixDto,) async {
|
||||||
|
final response = await fixAuditFilesWithHttpInfo(fileReportFixDto,);
|
||||||
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Performs an HTTP 'GET /report' operation and returns the [Response].
|
||||||
|
Future<Response> getAuditFilesWithHttpInfo() async {
|
||||||
|
// ignore: prefer_const_declarations
|
||||||
|
final path = r'/report';
|
||||||
|
|
||||||
|
// ignore: prefer_final_locals
|
||||||
|
Object? postBody;
|
||||||
|
|
||||||
|
final queryParams = <QueryParam>[];
|
||||||
|
final headerParams = <String, String>{};
|
||||||
|
final formParams = <String, String>{};
|
||||||
|
|
||||||
|
const contentTypes = <String>[];
|
||||||
|
|
||||||
|
|
||||||
|
return apiClient.invokeAPI(
|
||||||
|
path,
|
||||||
|
'GET',
|
||||||
|
queryParams,
|
||||||
|
postBody,
|
||||||
|
headerParams,
|
||||||
|
formParams,
|
||||||
|
contentTypes.isEmpty ? null : contentTypes.first,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<FileReportDto?> getAuditFiles() async {
|
||||||
|
final response = await getAuditFilesWithHttpInfo();
|
||||||
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
|
}
|
||||||
|
// When a remote server returns no body with a status of 204, we shall not decode it.
|
||||||
|
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||||
|
// FormatException when trying to decode an empty string.
|
||||||
|
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||||
|
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'FileReportDto',) as FileReportDto;
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Performs an HTTP 'POST /report/checksum' operation and returns the [Response].
|
||||||
|
/// Parameters:
|
||||||
|
///
|
||||||
|
/// * [FileChecksumDto] fileChecksumDto (required):
|
||||||
|
Future<Response> getFileChecksumsWithHttpInfo(FileChecksumDto fileChecksumDto,) async {
|
||||||
|
// ignore: prefer_const_declarations
|
||||||
|
final path = r'/report/checksum';
|
||||||
|
|
||||||
|
// ignore: prefer_final_locals
|
||||||
|
Object? postBody = fileChecksumDto;
|
||||||
|
|
||||||
|
final queryParams = <QueryParam>[];
|
||||||
|
final headerParams = <String, String>{};
|
||||||
|
final formParams = <String, String>{};
|
||||||
|
|
||||||
|
const contentTypes = <String>['application/json'];
|
||||||
|
|
||||||
|
|
||||||
|
return apiClient.invokeAPI(
|
||||||
|
path,
|
||||||
|
'POST',
|
||||||
|
queryParams,
|
||||||
|
postBody,
|
||||||
|
headerParams,
|
||||||
|
formParams,
|
||||||
|
contentTypes.isEmpty ? null : contentTypes.first,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parameters:
|
||||||
|
///
|
||||||
|
/// * [FileChecksumDto] fileChecksumDto (required):
|
||||||
|
Future<List<FileChecksumResponseDto>?> getFileChecksums(FileChecksumDto fileChecksumDto,) async {
|
||||||
|
final response = await getFileChecksumsWithHttpInfo(fileChecksumDto,);
|
||||||
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
|
}
|
||||||
|
// When a remote server returns no body with a status of 204, we shall not decode it.
|
||||||
|
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||||
|
// FormatException when trying to decode an empty string.
|
||||||
|
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||||
|
final responseBody = await _decodeBodyBytes(response);
|
||||||
|
return (await apiClient.deserializeAsync(responseBody, 'List<FileChecksumResponseDto>') as List)
|
||||||
|
.cast<FileChecksumResponseDto>()
|
||||||
|
.toList(growable: false);
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
-33
@@ -343,37 +343,4 @@ class ServerInfoApi {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Performs an HTTP 'POST /server-info/admin-onboarding' operation and returns the [Response].
|
|
||||||
Future<Response> setAdminOnboardingWithHttpInfo() async {
|
|
||||||
// ignore: prefer_const_declarations
|
|
||||||
final path = r'/server-info/admin-onboarding';
|
|
||||||
|
|
||||||
// ignore: prefer_final_locals
|
|
||||||
Object? postBody;
|
|
||||||
|
|
||||||
final queryParams = <QueryParam>[];
|
|
||||||
final headerParams = <String, String>{};
|
|
||||||
final formParams = <String, String>{};
|
|
||||||
|
|
||||||
const contentTypes = <String>[];
|
|
||||||
|
|
||||||
|
|
||||||
return apiClient.invokeAPI(
|
|
||||||
path,
|
|
||||||
'POST',
|
|
||||||
queryParams,
|
|
||||||
postBody,
|
|
||||||
headerParams,
|
|
||||||
formParams,
|
|
||||||
contentTypes.isEmpty ? null : contentTypes.first,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> setAdminOnboarding() async {
|
|
||||||
final response = await setAdminOnboardingWithHttpInfo();
|
|
||||||
if (response.statusCode >= HttpStatus.badRequest) {
|
|
||||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+139
@@ -0,0 +1,139 @@
|
|||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
part of openapi.api;
|
||||||
|
|
||||||
|
|
||||||
|
class SystemMetadataApi {
|
||||||
|
SystemMetadataApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient;
|
||||||
|
|
||||||
|
final ApiClient apiClient;
|
||||||
|
|
||||||
|
/// Performs an HTTP 'GET /system-metadata/admin-onboarding' operation and returns the [Response].
|
||||||
|
Future<Response> getAdminOnboardingWithHttpInfo() async {
|
||||||
|
// ignore: prefer_const_declarations
|
||||||
|
final path = r'/system-metadata/admin-onboarding';
|
||||||
|
|
||||||
|
// ignore: prefer_final_locals
|
||||||
|
Object? postBody;
|
||||||
|
|
||||||
|
final queryParams = <QueryParam>[];
|
||||||
|
final headerParams = <String, String>{};
|
||||||
|
final formParams = <String, String>{};
|
||||||
|
|
||||||
|
const contentTypes = <String>[];
|
||||||
|
|
||||||
|
|
||||||
|
return apiClient.invokeAPI(
|
||||||
|
path,
|
||||||
|
'GET',
|
||||||
|
queryParams,
|
||||||
|
postBody,
|
||||||
|
headerParams,
|
||||||
|
formParams,
|
||||||
|
contentTypes.isEmpty ? null : contentTypes.first,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<AdminOnboardingUpdateDto?> getAdminOnboarding() async {
|
||||||
|
final response = await getAdminOnboardingWithHttpInfo();
|
||||||
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
|
}
|
||||||
|
// When a remote server returns no body with a status of 204, we shall not decode it.
|
||||||
|
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||||
|
// FormatException when trying to decode an empty string.
|
||||||
|
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||||
|
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AdminOnboardingUpdateDto',) as AdminOnboardingUpdateDto;
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Performs an HTTP 'GET /system-metadata/reverse-geocoding-state' operation and returns the [Response].
|
||||||
|
Future<Response> getReverseGeocodingStateWithHttpInfo() async {
|
||||||
|
// ignore: prefer_const_declarations
|
||||||
|
final path = r'/system-metadata/reverse-geocoding-state';
|
||||||
|
|
||||||
|
// ignore: prefer_final_locals
|
||||||
|
Object? postBody;
|
||||||
|
|
||||||
|
final queryParams = <QueryParam>[];
|
||||||
|
final headerParams = <String, String>{};
|
||||||
|
final formParams = <String, String>{};
|
||||||
|
|
||||||
|
const contentTypes = <String>[];
|
||||||
|
|
||||||
|
|
||||||
|
return apiClient.invokeAPI(
|
||||||
|
path,
|
||||||
|
'GET',
|
||||||
|
queryParams,
|
||||||
|
postBody,
|
||||||
|
headerParams,
|
||||||
|
formParams,
|
||||||
|
contentTypes.isEmpty ? null : contentTypes.first,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ReverseGeocodingStateResponseDto?> getReverseGeocodingState() async {
|
||||||
|
final response = await getReverseGeocodingStateWithHttpInfo();
|
||||||
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
|
}
|
||||||
|
// When a remote server returns no body with a status of 204, we shall not decode it.
|
||||||
|
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||||
|
// FormatException when trying to decode an empty string.
|
||||||
|
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||||
|
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'ReverseGeocodingStateResponseDto',) as ReverseGeocodingStateResponseDto;
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Performs an HTTP 'POST /system-metadata/admin-onboarding' operation and returns the [Response].
|
||||||
|
/// Parameters:
|
||||||
|
///
|
||||||
|
/// * [AdminOnboardingUpdateDto] adminOnboardingUpdateDto (required):
|
||||||
|
Future<Response> updateAdminOnboardingWithHttpInfo(AdminOnboardingUpdateDto adminOnboardingUpdateDto,) async {
|
||||||
|
// ignore: prefer_const_declarations
|
||||||
|
final path = r'/system-metadata/admin-onboarding';
|
||||||
|
|
||||||
|
// ignore: prefer_final_locals
|
||||||
|
Object? postBody = adminOnboardingUpdateDto;
|
||||||
|
|
||||||
|
final queryParams = <QueryParam>[];
|
||||||
|
final headerParams = <String, String>{};
|
||||||
|
final formParams = <String, String>{};
|
||||||
|
|
||||||
|
const contentTypes = <String>['application/json'];
|
||||||
|
|
||||||
|
|
||||||
|
return apiClient.invokeAPI(
|
||||||
|
path,
|
||||||
|
'POST',
|
||||||
|
queryParams,
|
||||||
|
postBody,
|
||||||
|
headerParams,
|
||||||
|
formParams,
|
||||||
|
contentTypes.isEmpty ? null : contentTypes.first,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parameters:
|
||||||
|
///
|
||||||
|
/// * [AdminOnboardingUpdateDto] adminOnboardingUpdateDto (required):
|
||||||
|
Future<void> updateAdminOnboarding(AdminOnboardingUpdateDto adminOnboardingUpdateDto,) async {
|
||||||
|
final response = await updateAdminOnboardingWithHttpInfo(adminOnboardingUpdateDto,);
|
||||||
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+4
-6
@@ -198,14 +198,12 @@ class ApiClient {
|
|||||||
return ActivityStatisticsResponseDto.fromJson(value);
|
return ActivityStatisticsResponseDto.fromJson(value);
|
||||||
case 'AddUsersDto':
|
case 'AddUsersDto':
|
||||||
return AddUsersDto.fromJson(value);
|
return AddUsersDto.fromJson(value);
|
||||||
|
case 'AdminOnboardingUpdateDto':
|
||||||
|
return AdminOnboardingUpdateDto.fromJson(value);
|
||||||
case 'AlbumCountResponseDto':
|
case 'AlbumCountResponseDto':
|
||||||
return AlbumCountResponseDto.fromJson(value);
|
return AlbumCountResponseDto.fromJson(value);
|
||||||
case 'AlbumResponseDto':
|
case 'AlbumResponseDto':
|
||||||
return AlbumResponseDto.fromJson(value);
|
return AlbumResponseDto.fromJson(value);
|
||||||
case 'AlbumUserResponseDto':
|
|
||||||
return AlbumUserResponseDto.fromJson(value);
|
|
||||||
case 'AlbumUserRole':
|
|
||||||
return AlbumUserRoleTypeTransformer().decode(value);
|
|
||||||
case 'AllJobStatusResponseDto':
|
case 'AllJobStatusResponseDto':
|
||||||
return AllJobStatusResponseDto.fromJson(value);
|
return AllJobStatusResponseDto.fromJson(value);
|
||||||
case 'AssetBulkDeleteDto':
|
case 'AssetBulkDeleteDto':
|
||||||
@@ -396,6 +394,8 @@ class ApiClient {
|
|||||||
return ReactionTypeTypeTransformer().decode(value);
|
return ReactionTypeTypeTransformer().decode(value);
|
||||||
case 'RecognitionConfig':
|
case 'RecognitionConfig':
|
||||||
return RecognitionConfig.fromJson(value);
|
return RecognitionConfig.fromJson(value);
|
||||||
|
case 'ReverseGeocodingStateResponseDto':
|
||||||
|
return ReverseGeocodingStateResponseDto.fromJson(value);
|
||||||
case 'ScanLibraryDto':
|
case 'ScanLibraryDto':
|
||||||
return ScanLibraryDto.fromJson(value);
|
return ScanLibraryDto.fromJson(value);
|
||||||
case 'SearchAlbumResponseDto':
|
case 'SearchAlbumResponseDto':
|
||||||
@@ -504,8 +504,6 @@ class ApiClient {
|
|||||||
return TranscodePolicyTypeTransformer().decode(value);
|
return TranscodePolicyTypeTransformer().decode(value);
|
||||||
case 'UpdateAlbumDto':
|
case 'UpdateAlbumDto':
|
||||||
return UpdateAlbumDto.fromJson(value);
|
return UpdateAlbumDto.fromJson(value);
|
||||||
case 'UpdateAlbumUserDto':
|
|
||||||
return UpdateAlbumUserDto.fromJson(value);
|
|
||||||
case 'UpdateAssetDto':
|
case 'UpdateAssetDto':
|
||||||
return UpdateAssetDto.fromJson(value);
|
return UpdateAssetDto.fromJson(value);
|
||||||
case 'UpdateLibraryDto':
|
case 'UpdateLibraryDto':
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
part of openapi.api;
|
||||||
|
|
||||||
|
class AdminOnboardingUpdateDto {
|
||||||
|
/// Returns a new [AdminOnboardingUpdateDto] instance.
|
||||||
|
AdminOnboardingUpdateDto({
|
||||||
|
required this.isOnboarded,
|
||||||
|
});
|
||||||
|
|
||||||
|
bool isOnboarded;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) => identical(this, other) || other is AdminOnboardingUpdateDto &&
|
||||||
|
other.isOnboarded == isOnboarded;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
// ignore: unnecessary_parenthesis
|
||||||
|
(isOnboarded.hashCode);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'AdminOnboardingUpdateDto[isOnboarded=$isOnboarded]';
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final json = <String, dynamic>{};
|
||||||
|
json[r'isOnboarded'] = this.isOnboarded;
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new [AdminOnboardingUpdateDto] instance and imports its values from
|
||||||
|
/// [value] if it's a [Map], null otherwise.
|
||||||
|
// ignore: prefer_constructors_over_static_methods
|
||||||
|
static AdminOnboardingUpdateDto? fromJson(dynamic value) {
|
||||||
|
if (value is Map) {
|
||||||
|
final json = value.cast<String, dynamic>();
|
||||||
|
|
||||||
|
return AdminOnboardingUpdateDto(
|
||||||
|
isOnboarded: mapValueOfType<bool>(json, r'isOnboarded')!,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<AdminOnboardingUpdateDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final result = <AdminOnboardingUpdateDto>[];
|
||||||
|
if (json is List && json.isNotEmpty) {
|
||||||
|
for (final row in json) {
|
||||||
|
final value = AdminOnboardingUpdateDto.fromJson(row);
|
||||||
|
if (value != null) {
|
||||||
|
result.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toList(growable: growable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Map<String, AdminOnboardingUpdateDto> mapFromJson(dynamic json) {
|
||||||
|
final map = <String, AdminOnboardingUpdateDto>{};
|
||||||
|
if (json is Map && json.isNotEmpty) {
|
||||||
|
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||||
|
for (final entry in json.entries) {
|
||||||
|
final value = AdminOnboardingUpdateDto.fromJson(entry.value);
|
||||||
|
if (value != null) {
|
||||||
|
map[entry.key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
// maps a json object with a list of AdminOnboardingUpdateDto-objects as value to a dart map
|
||||||
|
static Map<String, List<AdminOnboardingUpdateDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final map = <String, List<AdminOnboardingUpdateDto>>{};
|
||||||
|
if (json is Map && json.isNotEmpty) {
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
json = json.cast<String, dynamic>();
|
||||||
|
for (final entry in json.entries) {
|
||||||
|
map[entry.key] = AdminOnboardingUpdateDto.listFromJson(entry.value, growable: growable,);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The list of required keys that must be present in a JSON.
|
||||||
|
static const requiredKeys = <String>{
|
||||||
|
'isOnboarded',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
part of openapi.api;
|
||||||
|
|
||||||
|
class ReverseGeocodingStateResponseDto {
|
||||||
|
/// Returns a new [ReverseGeocodingStateResponseDto] instance.
|
||||||
|
ReverseGeocodingStateResponseDto({
|
||||||
|
required this.lastImportFileName,
|
||||||
|
required this.lastUpdate,
|
||||||
|
});
|
||||||
|
|
||||||
|
String? lastImportFileName;
|
||||||
|
|
||||||
|
String? lastUpdate;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) => identical(this, other) || other is ReverseGeocodingStateResponseDto &&
|
||||||
|
other.lastImportFileName == lastImportFileName &&
|
||||||
|
other.lastUpdate == lastUpdate;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
// ignore: unnecessary_parenthesis
|
||||||
|
(lastImportFileName == null ? 0 : lastImportFileName!.hashCode) +
|
||||||
|
(lastUpdate == null ? 0 : lastUpdate!.hashCode);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'ReverseGeocodingStateResponseDto[lastImportFileName=$lastImportFileName, lastUpdate=$lastUpdate]';
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final json = <String, dynamic>{};
|
||||||
|
if (this.lastImportFileName != null) {
|
||||||
|
json[r'lastImportFileName'] = this.lastImportFileName;
|
||||||
|
} else {
|
||||||
|
// json[r'lastImportFileName'] = null;
|
||||||
|
}
|
||||||
|
if (this.lastUpdate != null) {
|
||||||
|
json[r'lastUpdate'] = this.lastUpdate;
|
||||||
|
} else {
|
||||||
|
// json[r'lastUpdate'] = null;
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new [ReverseGeocodingStateResponseDto] instance and imports its values from
|
||||||
|
/// [value] if it's a [Map], null otherwise.
|
||||||
|
// ignore: prefer_constructors_over_static_methods
|
||||||
|
static ReverseGeocodingStateResponseDto? fromJson(dynamic value) {
|
||||||
|
if (value is Map) {
|
||||||
|
final json = value.cast<String, dynamic>();
|
||||||
|
|
||||||
|
return ReverseGeocodingStateResponseDto(
|
||||||
|
lastImportFileName: mapValueOfType<String>(json, r'lastImportFileName'),
|
||||||
|
lastUpdate: mapValueOfType<String>(json, r'lastUpdate'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<ReverseGeocodingStateResponseDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final result = <ReverseGeocodingStateResponseDto>[];
|
||||||
|
if (json is List && json.isNotEmpty) {
|
||||||
|
for (final row in json) {
|
||||||
|
final value = ReverseGeocodingStateResponseDto.fromJson(row);
|
||||||
|
if (value != null) {
|
||||||
|
result.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toList(growable: growable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Map<String, ReverseGeocodingStateResponseDto> mapFromJson(dynamic json) {
|
||||||
|
final map = <String, ReverseGeocodingStateResponseDto>{};
|
||||||
|
if (json is Map && json.isNotEmpty) {
|
||||||
|
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||||
|
for (final entry in json.entries) {
|
||||||
|
final value = ReverseGeocodingStateResponseDto.fromJson(entry.value);
|
||||||
|
if (value != null) {
|
||||||
|
map[entry.key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
// maps a json object with a list of ReverseGeocodingStateResponseDto-objects as value to a dart map
|
||||||
|
static Map<String, List<ReverseGeocodingStateResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final map = <String, List<ReverseGeocodingStateResponseDto>>{};
|
||||||
|
if (json is Map && json.isNotEmpty) {
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
json = json.cast<String, dynamic>();
|
||||||
|
for (final entry in json.entries) {
|
||||||
|
map[entry.key] = ReverseGeocodingStateResponseDto.listFromJson(entry.value, growable: growable,);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The list of required keys that must be present in a JSON.
|
||||||
|
static const requiredKeys = <String>{
|
||||||
|
'lastImportFileName',
|
||||||
|
'lastUpdate',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
+9
-1
@@ -14,6 +14,7 @@ class SystemConfigImageDto {
|
|||||||
/// Returns a new [SystemConfigImageDto] instance.
|
/// Returns a new [SystemConfigImageDto] instance.
|
||||||
SystemConfigImageDto({
|
SystemConfigImageDto({
|
||||||
required this.colorspace,
|
required this.colorspace,
|
||||||
|
required this.extractEmbedded,
|
||||||
required this.previewFormat,
|
required this.previewFormat,
|
||||||
required this.previewSize,
|
required this.previewSize,
|
||||||
required this.quality,
|
required this.quality,
|
||||||
@@ -23,6 +24,8 @@ class SystemConfigImageDto {
|
|||||||
|
|
||||||
Colorspace colorspace;
|
Colorspace colorspace;
|
||||||
|
|
||||||
|
bool extractEmbedded;
|
||||||
|
|
||||||
ImageFormat previewFormat;
|
ImageFormat previewFormat;
|
||||||
|
|
||||||
int previewSize;
|
int previewSize;
|
||||||
@@ -36,6 +39,7 @@ class SystemConfigImageDto {
|
|||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is SystemConfigImageDto &&
|
bool operator ==(Object other) => identical(this, other) || other is SystemConfigImageDto &&
|
||||||
other.colorspace == colorspace &&
|
other.colorspace == colorspace &&
|
||||||
|
other.extractEmbedded == extractEmbedded &&
|
||||||
other.previewFormat == previewFormat &&
|
other.previewFormat == previewFormat &&
|
||||||
other.previewSize == previewSize &&
|
other.previewSize == previewSize &&
|
||||||
other.quality == quality &&
|
other.quality == quality &&
|
||||||
@@ -46,6 +50,7 @@ class SystemConfigImageDto {
|
|||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
// ignore: unnecessary_parenthesis
|
// ignore: unnecessary_parenthesis
|
||||||
(colorspace.hashCode) +
|
(colorspace.hashCode) +
|
||||||
|
(extractEmbedded.hashCode) +
|
||||||
(previewFormat.hashCode) +
|
(previewFormat.hashCode) +
|
||||||
(previewSize.hashCode) +
|
(previewSize.hashCode) +
|
||||||
(quality.hashCode) +
|
(quality.hashCode) +
|
||||||
@@ -53,11 +58,12 @@ class SystemConfigImageDto {
|
|||||||
(thumbnailSize.hashCode);
|
(thumbnailSize.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'SystemConfigImageDto[colorspace=$colorspace, previewFormat=$previewFormat, previewSize=$previewSize, quality=$quality, thumbnailFormat=$thumbnailFormat, thumbnailSize=$thumbnailSize]';
|
String toString() => 'SystemConfigImageDto[colorspace=$colorspace, extractEmbedded=$extractEmbedded, previewFormat=$previewFormat, previewSize=$previewSize, quality=$quality, thumbnailFormat=$thumbnailFormat, thumbnailSize=$thumbnailSize]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
json[r'colorspace'] = this.colorspace;
|
json[r'colorspace'] = this.colorspace;
|
||||||
|
json[r'extractEmbedded'] = this.extractEmbedded;
|
||||||
json[r'previewFormat'] = this.previewFormat;
|
json[r'previewFormat'] = this.previewFormat;
|
||||||
json[r'previewSize'] = this.previewSize;
|
json[r'previewSize'] = this.previewSize;
|
||||||
json[r'quality'] = this.quality;
|
json[r'quality'] = this.quality;
|
||||||
@@ -75,6 +81,7 @@ class SystemConfigImageDto {
|
|||||||
|
|
||||||
return SystemConfigImageDto(
|
return SystemConfigImageDto(
|
||||||
colorspace: Colorspace.fromJson(json[r'colorspace'])!,
|
colorspace: Colorspace.fromJson(json[r'colorspace'])!,
|
||||||
|
extractEmbedded: mapValueOfType<bool>(json, r'extractEmbedded')!,
|
||||||
previewFormat: ImageFormat.fromJson(json[r'previewFormat'])!,
|
previewFormat: ImageFormat.fromJson(json[r'previewFormat'])!,
|
||||||
previewSize: mapValueOfType<int>(json, r'previewSize')!,
|
previewSize: mapValueOfType<int>(json, r'previewSize')!,
|
||||||
quality: mapValueOfType<int>(json, r'quality')!,
|
quality: mapValueOfType<int>(json, r'quality')!,
|
||||||
@@ -128,6 +135,7 @@ class SystemConfigImageDto {
|
|||||||
/// The list of required keys that must be present in a JSON.
|
/// The list of required keys that must be present in a JSON.
|
||||||
static const requiredKeys = <String>{
|
static const requiredKeys = <String>{
|
||||||
'colorspace',
|
'colorspace',
|
||||||
|
'extractEmbedded',
|
||||||
'previewFormat',
|
'previewFormat',
|
||||||
'previewSize',
|
'previewSize',
|
||||||
'quality',
|
'quality',
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
// tests for AdminOnboardingUpdateDto
|
||||||
|
void main() {
|
||||||
|
// final instance = AdminOnboardingUpdateDto();
|
||||||
|
|
||||||
|
group('test AdminOnboardingUpdateDto', () {
|
||||||
|
// bool isOnboarded
|
||||||
|
test('to test the property `isOnboarded`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
Generated
-15
@@ -17,25 +17,10 @@ void main() {
|
|||||||
// final instance = AuditApi();
|
// final instance = AuditApi();
|
||||||
|
|
||||||
group('tests for AuditApi', () {
|
group('tests for AuditApi', () {
|
||||||
//Future fixAuditFiles(FileReportFixDto fileReportFixDto) async
|
|
||||||
test('test fixAuditFiles', () async {
|
|
||||||
// TODO
|
|
||||||
});
|
|
||||||
|
|
||||||
//Future<AuditDeletesResponseDto> getAuditDeletes(DateTime after, EntityType entityType, { String userId }) async
|
//Future<AuditDeletesResponseDto> getAuditDeletes(DateTime after, EntityType entityType, { String userId }) async
|
||||||
test('test getAuditDeletes', () async {
|
test('test getAuditDeletes', () async {
|
||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
|
|
||||||
//Future<FileReportDto> getAuditFiles() async
|
|
||||||
test('test getAuditFiles', () async {
|
|
||||||
// TODO
|
|
||||||
});
|
|
||||||
|
|
||||||
//Future<List<FileChecksumResponseDto>> getFileChecksums(FileChecksumDto fileChecksumDto) async
|
|
||||||
test('test getFileChecksums', () async {
|
|
||||||
// TODO
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
|
||||||
|
/// tests for FileReportApi
|
||||||
|
void main() {
|
||||||
|
// final instance = FileReportApi();
|
||||||
|
|
||||||
|
group('tests for FileReportApi', () {
|
||||||
|
//Future fixAuditFiles(FileReportFixDto fileReportFixDto) async
|
||||||
|
test('test fixAuditFiles', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
//Future<FileReportDto> getAuditFiles() async
|
||||||
|
test('test getAuditFiles', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
//Future<List<FileChecksumResponseDto>> getFileChecksums(FileChecksumDto fileChecksumDto) async
|
||||||
|
test('test getFileChecksums', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
// tests for ReverseGeocodingStateResponseDto
|
||||||
|
void main() {
|
||||||
|
// final instance = ReverseGeocodingStateResponseDto();
|
||||||
|
|
||||||
|
group('test ReverseGeocodingStateResponseDto', () {
|
||||||
|
// String lastImportFileName
|
||||||
|
test('to test the property `lastImportFileName`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
// String lastUpdate
|
||||||
|
test('to test the property `lastUpdate`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
-5
@@ -57,10 +57,5 @@ void main() {
|
|||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
|
|
||||||
//Future setAdminOnboarding() async
|
|
||||||
test('test setAdminOnboarding', () async {
|
|
||||||
// TODO
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ void main() {
|
|||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// bool extractEmbedded
|
||||||
|
test('to test the property `extractEmbedded`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
// ImageFormat previewFormat
|
// ImageFormat previewFormat
|
||||||
test('to test the property `previewFormat`', () async {
|
test('to test the property `previewFormat`', () async {
|
||||||
// TODO
|
// TODO
|
||||||
|
|||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
|
||||||
|
/// tests for SystemMetadataApi
|
||||||
|
void main() {
|
||||||
|
// final instance = SystemMetadataApi();
|
||||||
|
|
||||||
|
group('tests for SystemMetadataApi', () {
|
||||||
|
//Future<AdminOnboardingUpdateDto> getAdminOnboarding() async
|
||||||
|
test('test getAdminOnboarding', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
//Future<ReverseGeocodingStateResponseDto> getReverseGeocodingState() async
|
||||||
|
test('test getReverseGeocodingState', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
//Future updateAdminOnboarding(AdminOnboardingUpdateDto adminOnboardingUpdateDto) async
|
||||||
|
test('test updateAdminOnboarding', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
+1
-1
@@ -1804,5 +1804,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.2"
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.2.0 <4.0.0"
|
dart: ">=3.3.0 <4.0.0"
|
||||||
flutter: ">=3.16.0"
|
flutter: ">=3.16.0"
|
||||||
|
|||||||
+2
-2
@@ -2,10 +2,10 @@ name: immich_mobile
|
|||||||
description: Immich - selfhosted backup media file on mobile phone
|
description: Immich - selfhosted backup media file on mobile phone
|
||||||
|
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
version: 1.101.0+131
|
version: 1.102.3+136
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.0.0 <4.0.0'
|
sdk: '>=3.3.0 <4.0.0'
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
|
|||||||
+242
-138
@@ -2398,118 +2398,6 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/audit/file-report": {
|
|
||||||
"get": {
|
|
||||||
"operationId": "getAuditFiles",
|
|
||||||
"parameters": [],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/FileReportDto"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"bearer": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cookie": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"api_key": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Audit"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/audit/file-report/checksum": {
|
|
||||||
"post": {
|
|
||||||
"operationId": "getFileChecksums",
|
|
||||||
"parameters": [],
|
|
||||||
"requestBody": {
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/FileChecksumDto"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"responses": {
|
|
||||||
"201": {
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/components/schemas/FileChecksumResponseDto"
|
|
||||||
},
|
|
||||||
"type": "array"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"bearer": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cookie": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"api_key": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Audit"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/audit/file-report/fix": {
|
|
||||||
"post": {
|
|
||||||
"operationId": "fixAuditFiles",
|
|
||||||
"parameters": [],
|
|
||||||
"requestBody": {
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/FileReportFixDto"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"responses": {
|
|
||||||
"201": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"bearer": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cookie": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"api_key": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Audit"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/auth/admin-sign-up": {
|
"/auth/admin-sign-up": {
|
||||||
"post": {
|
"post": {
|
||||||
"operationId": "signUpAdmin",
|
"operationId": "signUpAdmin",
|
||||||
@@ -4482,6 +4370,118 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/report": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "getAuditFiles",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/FileReportDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"bearer": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cookie": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"api_key": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"File Report"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/report/checksum": {
|
||||||
|
"post": {
|
||||||
|
"operationId": "getFileChecksums",
|
||||||
|
"parameters": [],
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/FileChecksumDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/FileChecksumResponseDto"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"bearer": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cookie": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"api_key": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"File Report"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/report/fix": {
|
||||||
|
"post": {
|
||||||
|
"operationId": "fixAuditFiles",
|
||||||
|
"parameters": [],
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/FileReportFixDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"bearer": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cookie": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"api_key": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"File Report"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/search": {
|
"/search": {
|
||||||
"get": {
|
"get": {
|
||||||
"deprecated": true,
|
"deprecated": true,
|
||||||
@@ -4961,31 +4961,6 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/server-info/admin-onboarding": {
|
|
||||||
"post": {
|
|
||||||
"operationId": "setAdminOnboarding",
|
|
||||||
"parameters": [],
|
|
||||||
"responses": {
|
|
||||||
"204": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"bearer": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cookie": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"api_key": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Server Info"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/server-info/config": {
|
"/server-info/config": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "getServerConfig",
|
"operationId": "getServerConfig",
|
||||||
@@ -5938,6 +5913,103 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/system-metadata/admin-onboarding": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "getAdminOnboarding",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/AdminOnboardingUpdateDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"bearer": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cookie": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"api_key": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"System Metadata"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"operationId": "updateAdminOnboarding",
|
||||||
|
"parameters": [],
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/AdminOnboardingUpdateDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"bearer": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cookie": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"api_key": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"System Metadata"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/system-metadata/reverse-geocoding-state": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "getReverseGeocodingState",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ReverseGeocodingStateResponseDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"bearer": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cookie": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"api_key": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"System Metadata"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/tag": {
|
"/tag": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "getAllTags",
|
"operationId": "getAllTags",
|
||||||
@@ -7059,7 +7131,7 @@
|
|||||||
"info": {
|
"info": {
|
||||||
"title": "Immich",
|
"title": "Immich",
|
||||||
"description": "Immich API",
|
"description": "Immich API",
|
||||||
"version": "1.101.0",
|
"version": "1.102.3",
|
||||||
"contact": {}
|
"contact": {}
|
||||||
},
|
},
|
||||||
"tags": [],
|
"tags": [],
|
||||||
@@ -7233,6 +7305,17 @@
|
|||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"AdminOnboardingUpdateDto": {
|
||||||
|
"properties": {
|
||||||
|
"isOnboarded": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"isOnboarded"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"AlbumCountResponseDto": {
|
"AlbumCountResponseDto": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"notShared": {
|
"notShared": {
|
||||||
@@ -9702,6 +9785,23 @@
|
|||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"ReverseGeocodingStateResponseDto": {
|
||||||
|
"properties": {
|
||||||
|
"lastImportFileName": {
|
||||||
|
"nullable": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"lastUpdate": {
|
||||||
|
"nullable": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"lastImportFileName",
|
||||||
|
"lastUpdate"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"ScanLibraryDto": {
|
"ScanLibraryDto": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"refreshAllFiles": {
|
"refreshAllFiles": {
|
||||||
@@ -10615,6 +10715,9 @@
|
|||||||
"colorspace": {
|
"colorspace": {
|
||||||
"$ref": "#/components/schemas/Colorspace"
|
"$ref": "#/components/schemas/Colorspace"
|
||||||
},
|
},
|
||||||
|
"extractEmbedded": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"previewFormat": {
|
"previewFormat": {
|
||||||
"$ref": "#/components/schemas/ImageFormat"
|
"$ref": "#/components/schemas/ImageFormat"
|
||||||
},
|
},
|
||||||
@@ -10633,6 +10736,7 @@
|
|||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"colorspace",
|
"colorspace",
|
||||||
|
"extractEmbedded",
|
||||||
"previewFormat",
|
"previewFormat",
|
||||||
"previewSize",
|
"previewSize",
|
||||||
"quality",
|
"quality",
|
||||||
|
|||||||
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@immich/sdk",
|
"name": "@immich/sdk",
|
||||||
"version": "1.101.0",
|
"version": "1.102.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@immich/sdk",
|
"name": "@immich/sdk",
|
||||||
"version": "1.101.0",
|
"version": "1.102.3",
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@oazapfts/runtime": "^1.0.2"
|
"@oazapfts/runtime": "^1.0.2"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@immich/sdk",
|
"name": "@immich/sdk",
|
||||||
"version": "1.101.0",
|
"version": "1.102.3",
|
||||||
"description": "Auto-generated TypeScript SDK for the Immich API",
|
"description": "Auto-generated TypeScript SDK for the Immich API",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./build/index.js",
|
"main": "./build/index.js",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Immich
|
* Immich
|
||||||
* 1.101.0
|
* 1.102.3
|
||||||
* DO NOT MODIFY - This file has been generated using oazapfts.
|
* DO NOT MODIFY - This file has been generated using oazapfts.
|
||||||
* See https://www.npmjs.com/package/oazapfts
|
* See https://www.npmjs.com/package/oazapfts
|
||||||
*/
|
*/
|
||||||
@@ -325,27 +325,6 @@ export type AuditDeletesResponseDto = {
|
|||||||
ids: string[];
|
ids: string[];
|
||||||
needsFullSync: boolean;
|
needsFullSync: boolean;
|
||||||
};
|
};
|
||||||
export type FileReportItemDto = {
|
|
||||||
checksum?: string;
|
|
||||||
entityId: string;
|
|
||||||
entityType: PathEntityType;
|
|
||||||
pathType: PathType;
|
|
||||||
pathValue: string;
|
|
||||||
};
|
|
||||||
export type FileReportDto = {
|
|
||||||
extras: string[];
|
|
||||||
orphans: FileReportItemDto[];
|
|
||||||
};
|
|
||||||
export type FileChecksumDto = {
|
|
||||||
filenames: string[];
|
|
||||||
};
|
|
||||||
export type FileChecksumResponseDto = {
|
|
||||||
checksum: string;
|
|
||||||
filename: string;
|
|
||||||
};
|
|
||||||
export type FileReportFixDto = {
|
|
||||||
items: FileReportItemDto[];
|
|
||||||
};
|
|
||||||
export type SignUpDto = {
|
export type SignUpDto = {
|
||||||
email: string;
|
email: string;
|
||||||
name: string;
|
name: string;
|
||||||
@@ -608,6 +587,27 @@ export type AssetFaceUpdateDto = {
|
|||||||
export type PersonStatisticsResponseDto = {
|
export type PersonStatisticsResponseDto = {
|
||||||
assets: number;
|
assets: number;
|
||||||
};
|
};
|
||||||
|
export type FileReportItemDto = {
|
||||||
|
checksum?: string;
|
||||||
|
entityId: string;
|
||||||
|
entityType: PathEntityType;
|
||||||
|
pathType: PathType;
|
||||||
|
pathValue: string;
|
||||||
|
};
|
||||||
|
export type FileReportDto = {
|
||||||
|
extras: string[];
|
||||||
|
orphans: FileReportItemDto[];
|
||||||
|
};
|
||||||
|
export type FileChecksumDto = {
|
||||||
|
filenames: string[];
|
||||||
|
};
|
||||||
|
export type FileChecksumResponseDto = {
|
||||||
|
checksum: string;
|
||||||
|
filename: string;
|
||||||
|
};
|
||||||
|
export type FileReportFixDto = {
|
||||||
|
items: FileReportItemDto[];
|
||||||
|
};
|
||||||
export type SearchFacetCountResponseDto = {
|
export type SearchFacetCountResponseDto = {
|
||||||
count: number;
|
count: number;
|
||||||
value: string;
|
value: string;
|
||||||
@@ -873,6 +873,7 @@ export type SystemConfigFFmpegDto = {
|
|||||||
};
|
};
|
||||||
export type SystemConfigImageDto = {
|
export type SystemConfigImageDto = {
|
||||||
colorspace: Colorspace;
|
colorspace: Colorspace;
|
||||||
|
extractEmbedded: boolean;
|
||||||
previewFormat: ImageFormat;
|
previewFormat: ImageFormat;
|
||||||
previewSize: number;
|
previewSize: number;
|
||||||
quality: number;
|
quality: number;
|
||||||
@@ -1006,6 +1007,13 @@ export type SystemConfigTemplateStorageOptionDto = {
|
|||||||
weekOptions: string[];
|
weekOptions: string[];
|
||||||
yearOptions: string[];
|
yearOptions: string[];
|
||||||
};
|
};
|
||||||
|
export type AdminOnboardingUpdateDto = {
|
||||||
|
isOnboarded: boolean;
|
||||||
|
};
|
||||||
|
export type ReverseGeocodingStateResponseDto = {
|
||||||
|
lastImportFileName: string | null;
|
||||||
|
lastUpdate: string | null;
|
||||||
|
};
|
||||||
export type CreateTagDto = {
|
export type CreateTagDto = {
|
||||||
name: string;
|
name: string;
|
||||||
"type": TagTypeEnum;
|
"type": TagTypeEnum;
|
||||||
@@ -1670,35 +1678,6 @@ export function getAuditDeletes({ after, entityType, userId }: {
|
|||||||
...opts
|
...opts
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
export function getAuditFiles(opts?: Oazapfts.RequestOpts) {
|
|
||||||
return oazapfts.ok(oazapfts.fetchJson<{
|
|
||||||
status: 200;
|
|
||||||
data: FileReportDto;
|
|
||||||
}>("/audit/file-report", {
|
|
||||||
...opts
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
export function getFileChecksums({ fileChecksumDto }: {
|
|
||||||
fileChecksumDto: FileChecksumDto;
|
|
||||||
}, opts?: Oazapfts.RequestOpts) {
|
|
||||||
return oazapfts.ok(oazapfts.fetchJson<{
|
|
||||||
status: 201;
|
|
||||||
data: FileChecksumResponseDto[];
|
|
||||||
}>("/audit/file-report/checksum", oazapfts.json({
|
|
||||||
...opts,
|
|
||||||
method: "POST",
|
|
||||||
body: fileChecksumDto
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
export function fixAuditFiles({ fileReportFixDto }: {
|
|
||||||
fileReportFixDto: FileReportFixDto;
|
|
||||||
}, opts?: Oazapfts.RequestOpts) {
|
|
||||||
return oazapfts.ok(oazapfts.fetchText("/audit/file-report/fix", oazapfts.json({
|
|
||||||
...opts,
|
|
||||||
method: "POST",
|
|
||||||
body: fileReportFixDto
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
export function signUpAdmin({ signUpDto }: {
|
export function signUpAdmin({ signUpDto }: {
|
||||||
signUpDto: SignUpDto;
|
signUpDto: SignUpDto;
|
||||||
}, opts?: Oazapfts.RequestOpts) {
|
}, opts?: Oazapfts.RequestOpts) {
|
||||||
@@ -2225,6 +2204,35 @@ export function getPersonThumbnail({ id }: {
|
|||||||
...opts
|
...opts
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
export function getAuditFiles(opts?: Oazapfts.RequestOpts) {
|
||||||
|
return oazapfts.ok(oazapfts.fetchJson<{
|
||||||
|
status: 200;
|
||||||
|
data: FileReportDto;
|
||||||
|
}>("/report", {
|
||||||
|
...opts
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
export function getFileChecksums({ fileChecksumDto }: {
|
||||||
|
fileChecksumDto: FileChecksumDto;
|
||||||
|
}, opts?: Oazapfts.RequestOpts) {
|
||||||
|
return oazapfts.ok(oazapfts.fetchJson<{
|
||||||
|
status: 201;
|
||||||
|
data: FileChecksumResponseDto[];
|
||||||
|
}>("/report/checksum", oazapfts.json({
|
||||||
|
...opts,
|
||||||
|
method: "POST",
|
||||||
|
body: fileChecksumDto
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
export function fixAuditFiles({ fileReportFixDto }: {
|
||||||
|
fileReportFixDto: FileReportFixDto;
|
||||||
|
}, opts?: Oazapfts.RequestOpts) {
|
||||||
|
return oazapfts.ok(oazapfts.fetchText("/report/fix", oazapfts.json({
|
||||||
|
...opts,
|
||||||
|
method: "POST",
|
||||||
|
body: fileReportFixDto
|
||||||
|
})));
|
||||||
|
}
|
||||||
export function search({ clip, motion, page, q, query, recent, size, smart, $type, withArchived }: {
|
export function search({ clip, motion, page, q, query, recent, size, smart, $type, withArchived }: {
|
||||||
clip?: boolean;
|
clip?: boolean;
|
||||||
motion?: boolean;
|
motion?: boolean;
|
||||||
@@ -2349,12 +2357,6 @@ export function getServerInfo(opts?: Oazapfts.RequestOpts) {
|
|||||||
...opts
|
...opts
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
export function setAdminOnboarding(opts?: Oazapfts.RequestOpts) {
|
|
||||||
return oazapfts.ok(oazapfts.fetchText("/server-info/admin-onboarding", {
|
|
||||||
...opts,
|
|
||||||
method: "POST"
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
export function getServerConfig(opts?: Oazapfts.RequestOpts) {
|
export function getServerConfig(opts?: Oazapfts.RequestOpts) {
|
||||||
return oazapfts.ok(oazapfts.fetchJson<{
|
return oazapfts.ok(oazapfts.fetchJson<{
|
||||||
status: 200;
|
status: 200;
|
||||||
@@ -2616,6 +2618,31 @@ export function getStorageTemplateOptions(opts?: Oazapfts.RequestOpts) {
|
|||||||
...opts
|
...opts
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
export function getAdminOnboarding(opts?: Oazapfts.RequestOpts) {
|
||||||
|
return oazapfts.ok(oazapfts.fetchJson<{
|
||||||
|
status: 200;
|
||||||
|
data: AdminOnboardingUpdateDto;
|
||||||
|
}>("/system-metadata/admin-onboarding", {
|
||||||
|
...opts
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
export function updateAdminOnboarding({ adminOnboardingUpdateDto }: {
|
||||||
|
adminOnboardingUpdateDto: AdminOnboardingUpdateDto;
|
||||||
|
}, opts?: Oazapfts.RequestOpts) {
|
||||||
|
return oazapfts.ok(oazapfts.fetchText("/system-metadata/admin-onboarding", oazapfts.json({
|
||||||
|
...opts,
|
||||||
|
method: "POST",
|
||||||
|
body: adminOnboardingUpdateDto
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
export function getReverseGeocodingState(opts?: Oazapfts.RequestOpts) {
|
||||||
|
return oazapfts.ok(oazapfts.fetchJson<{
|
||||||
|
status: 200;
|
||||||
|
data: ReverseGeocodingStateResponseDto;
|
||||||
|
}>("/system-metadata/reverse-geocoding-state", {
|
||||||
|
...opts
|
||||||
|
}));
|
||||||
|
}
|
||||||
export function getAllTags(opts?: Oazapfts.RequestOpts) {
|
export function getAllTags(opts?: Oazapfts.RequestOpts) {
|
||||||
return oazapfts.ok(oazapfts.fetchJson<{
|
return oazapfts.ok(oazapfts.fetchJson<{
|
||||||
status: 200;
|
status: 200;
|
||||||
@@ -2971,20 +2998,6 @@ export enum EntityType {
|
|||||||
Asset = "ASSET",
|
Asset = "ASSET",
|
||||||
Album = "ALBUM"
|
Album = "ALBUM"
|
||||||
}
|
}
|
||||||
export enum PathEntityType {
|
|
||||||
Asset = "asset",
|
|
||||||
Person = "person",
|
|
||||||
User = "user"
|
|
||||||
}
|
|
||||||
export enum PathType {
|
|
||||||
Original = "original",
|
|
||||||
Preview = "preview",
|
|
||||||
Thumbnail = "thumbnail",
|
|
||||||
EncodedVideo = "encoded_video",
|
|
||||||
Sidecar = "sidecar",
|
|
||||||
Face = "face",
|
|
||||||
Profile = "profile"
|
|
||||||
}
|
|
||||||
export enum JobName {
|
export enum JobName {
|
||||||
ThumbnailGeneration = "thumbnailGeneration",
|
ThumbnailGeneration = "thumbnailGeneration",
|
||||||
MetadataExtraction = "metadataExtraction",
|
MetadataExtraction = "metadataExtraction",
|
||||||
@@ -3016,6 +3029,20 @@ export enum Type2 {
|
|||||||
export enum MemoryType {
|
export enum MemoryType {
|
||||||
OnThisDay = "on_this_day"
|
OnThisDay = "on_this_day"
|
||||||
}
|
}
|
||||||
|
export enum PathEntityType {
|
||||||
|
Asset = "asset",
|
||||||
|
Person = "person",
|
||||||
|
User = "user"
|
||||||
|
}
|
||||||
|
export enum PathType {
|
||||||
|
Original = "original",
|
||||||
|
Preview = "preview",
|
||||||
|
Thumbnail = "thumbnail",
|
||||||
|
EncodedVideo = "encoded_video",
|
||||||
|
Sidecar = "sidecar",
|
||||||
|
Face = "face",
|
||||||
|
Profile = "profile"
|
||||||
|
}
|
||||||
export enum SearchSuggestionType {
|
export enum SearchSuggestionType {
|
||||||
Country = "country",
|
Country = "country",
|
||||||
State = "state",
|
State = "state",
|
||||||
|
|||||||
+2
-1
@@ -27,7 +27,8 @@
|
|||||||
"matchFileNames": ["mobile/**"],
|
"matchFileNames": ["mobile/**"],
|
||||||
"groupName": "mobile",
|
"groupName": "mobile",
|
||||||
"matchUpdateTypes": ["minor", "patch"],
|
"matchUpdateTypes": ["minor", "patch"],
|
||||||
"schedule": "on tuesday"
|
"schedule": "on tuesday",
|
||||||
|
"addLabels": ["📱mobile"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"groupName": "exiftool",
|
"groupName": "exiftool",
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "immich",
|
"name": "immich",
|
||||||
"version": "1.101.0",
|
"version": "1.102.3",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "immich",
|
"name": "immich",
|
||||||
"version": "1.101.0",
|
"version": "1.102.3",
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nestjs/bullmq": "^10.0.1",
|
"@nestjs/bullmq": "^10.0.1",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "immich",
|
"name": "immich",
|
||||||
"version": "1.101.0",
|
"version": "1.102.3",
|
||||||
"description": "",
|
"description": "",
|
||||||
"author": "",
|
"author": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
|||||||
@@ -26,12 +26,7 @@ export const geodataCities500Path = join(GEODATA_ROOT_PATH, citiesFile);
|
|||||||
|
|
||||||
export const MOBILE_REDIRECT = 'app.immich:/';
|
export const MOBILE_REDIRECT = 'app.immich:/';
|
||||||
export const LOGIN_URL = '/auth/login?autoLaunch=0';
|
export const LOGIN_URL = '/auth/login?autoLaunch=0';
|
||||||
export const IMMICH_ACCESS_COOKIE = 'immich_access_token';
|
|
||||||
export const IMMICH_IS_AUTHENTICATED = 'immich_is_authenticated';
|
|
||||||
export const IMMICH_AUTH_TYPE_COOKIE = 'immich_auth_type';
|
|
||||||
export const IMMICH_API_KEY_NAME = 'api_key';
|
|
||||||
export const IMMICH_API_KEY_HEADER = 'x-api-key';
|
|
||||||
export const IMMICH_SHARED_LINK_ACCESS_COOKIE = 'immich_shared_link_token';
|
|
||||||
export enum AuthType {
|
export enum AuthType {
|
||||||
PASSWORD = 'password',
|
PASSWORD = 'password',
|
||||||
OAUTH = 'oauth',
|
OAUTH = 'oauth',
|
||||||
|
|||||||
@@ -1,15 +1,8 @@
|
|||||||
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
|
import { Controller, Get, Query } from '@nestjs/common';
|
||||||
import { ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import {
|
import { AuditDeletesDto, AuditDeletesResponseDto } from 'src/dtos/audit.dto';
|
||||||
AuditDeletesDto,
|
|
||||||
AuditDeletesResponseDto,
|
|
||||||
FileChecksumDto,
|
|
||||||
FileChecksumResponseDto,
|
|
||||||
FileReportDto,
|
|
||||||
FileReportFixDto,
|
|
||||||
} from 'src/dtos/audit.dto';
|
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { AdminRoute, Auth, Authenticated } from 'src/middleware/auth.guard';
|
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
||||||
import { AuditService } from 'src/services/audit.service';
|
import { AuditService } from 'src/services/audit.service';
|
||||||
|
|
||||||
@ApiTags('Audit')
|
@ApiTags('Audit')
|
||||||
@@ -22,22 +15,4 @@ export class AuditController {
|
|||||||
getAuditDeletes(@Auth() auth: AuthDto, @Query() dto: AuditDeletesDto): Promise<AuditDeletesResponseDto> {
|
getAuditDeletes(@Auth() auth: AuthDto, @Query() dto: AuditDeletesDto): Promise<AuditDeletesResponseDto> {
|
||||||
return this.service.getDeletes(auth, dto);
|
return this.service.getDeletes(auth, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AdminRoute()
|
|
||||||
@Get('file-report')
|
|
||||||
getAuditFiles(): Promise<FileReportDto> {
|
|
||||||
return this.service.getFileReport();
|
|
||||||
}
|
|
||||||
|
|
||||||
@AdminRoute()
|
|
||||||
@Post('file-report/checksum')
|
|
||||||
getFileChecksums(@Body() dto: FileChecksumDto): Promise<FileChecksumResponseDto[]> {
|
|
||||||
return this.service.getChecksums(dto);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AdminRoute()
|
|
||||||
@Post('file-report/fix')
|
|
||||||
fixAuditFiles(@Body() dto: FileReportFixDto): Promise<void> {
|
|
||||||
return this.service.fixItems(dto.items);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { Body, Controller, HttpCode, HttpStatus, Post, Req, Res } from '@nestjs/common';
|
import { Body, Controller, HttpCode, HttpStatus, Post, Req, Res } from '@nestjs/common';
|
||||||
import { ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { IMMICH_ACCESS_COOKIE, IMMICH_AUTH_TYPE_COOKIE, IMMICH_IS_AUTHENTICATED } from 'src/constants';
|
import { AuthType } from 'src/constants';
|
||||||
import {
|
import {
|
||||||
AuthDto,
|
AuthDto,
|
||||||
ChangePasswordDto,
|
ChangePasswordDto,
|
||||||
|
ImmichCookie,
|
||||||
LoginCredentialDto,
|
LoginCredentialDto,
|
||||||
LoginResponseDto,
|
LoginResponseDto,
|
||||||
LogoutResponseDto,
|
LogoutResponseDto,
|
||||||
@@ -14,6 +15,7 @@ import {
|
|||||||
import { UserResponseDto, mapUser } from 'src/dtos/user.dto';
|
import { UserResponseDto, mapUser } from 'src/dtos/user.dto';
|
||||||
import { Auth, Authenticated, GetLoginDetails, PublicRoute } from 'src/middleware/auth.guard';
|
import { Auth, Authenticated, GetLoginDetails, PublicRoute } from 'src/middleware/auth.guard';
|
||||||
import { AuthService, LoginDetails } from 'src/services/auth.service';
|
import { AuthService, LoginDetails } from 'src/services/auth.service';
|
||||||
|
import { respondWithCookie, respondWithoutCookie } from 'src/utils/response';
|
||||||
|
|
||||||
@ApiTags('Authentication')
|
@ApiTags('Authentication')
|
||||||
@Controller('auth')
|
@Controller('auth')
|
||||||
@@ -28,9 +30,15 @@ export class AuthController {
|
|||||||
@Res({ passthrough: true }) res: Response,
|
@Res({ passthrough: true }) res: Response,
|
||||||
@GetLoginDetails() loginDetails: LoginDetails,
|
@GetLoginDetails() loginDetails: LoginDetails,
|
||||||
): Promise<LoginResponseDto> {
|
): Promise<LoginResponseDto> {
|
||||||
const { response, cookie } = await this.service.login(loginCredential, loginDetails);
|
const body = await this.service.login(loginCredential, loginDetails);
|
||||||
res.header('Set-Cookie', cookie);
|
return respondWithCookie(res, body, {
|
||||||
return response;
|
isSecure: loginDetails.isSecure,
|
||||||
|
values: [
|
||||||
|
{ key: ImmichCookie.ACCESS_TOKEN, value: body.accessToken },
|
||||||
|
{ key: ImmichCookie.AUTH_TYPE, value: AuthType.PASSWORD },
|
||||||
|
{ key: ImmichCookie.IS_AUTHENTICATED, value: 'true' },
|
||||||
|
],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@PublicRoute()
|
@PublicRoute()
|
||||||
@@ -53,15 +61,18 @@ export class AuthController {
|
|||||||
|
|
||||||
@Post('logout')
|
@Post('logout')
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
logout(
|
async logout(
|
||||||
@Req() request: Request,
|
@Req() request: Request,
|
||||||
@Res({ passthrough: true }) res: Response,
|
@Res({ passthrough: true }) res: Response,
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
): Promise<LogoutResponseDto> {
|
): Promise<LogoutResponseDto> {
|
||||||
res.clearCookie(IMMICH_ACCESS_COOKIE);
|
const authType = (request.cookies || {})[ImmichCookie.AUTH_TYPE];
|
||||||
res.clearCookie(IMMICH_AUTH_TYPE_COOKIE);
|
|
||||||
res.clearCookie(IMMICH_IS_AUTHENTICATED);
|
|
||||||
|
|
||||||
return this.service.logout(auth, (request.cookies || {})[IMMICH_AUTH_TYPE_COOKIE]);
|
const body = await this.service.logout(auth, authType);
|
||||||
|
return respondWithoutCookie(res, body, [
|
||||||
|
ImmichCookie.ACCESS_TOKEN,
|
||||||
|
ImmichCookie.AUTH_TYPE,
|
||||||
|
ImmichCookie.IS_AUTHENTICATED,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { Body, Controller, Get, Post } from '@nestjs/common';
|
||||||
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { FileChecksumDto, FileChecksumResponseDto, FileReportDto, FileReportFixDto } from 'src/dtos/audit.dto';
|
||||||
|
import { AdminRoute, Authenticated } from 'src/middleware/auth.guard';
|
||||||
|
import { AuditService } from 'src/services/audit.service';
|
||||||
|
|
||||||
|
@ApiTags('File Report')
|
||||||
|
@Controller('report')
|
||||||
|
@Authenticated()
|
||||||
|
export class ReportController {
|
||||||
|
constructor(private service: AuditService) {}
|
||||||
|
|
||||||
|
@AdminRoute()
|
||||||
|
@Get()
|
||||||
|
getAuditFiles(): Promise<FileReportDto> {
|
||||||
|
return this.service.getFileReport();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AdminRoute()
|
||||||
|
@Post('/checksum')
|
||||||
|
getFileChecksums(@Body() dto: FileChecksumDto): Promise<FileChecksumResponseDto[]> {
|
||||||
|
return this.service.getChecksums(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AdminRoute()
|
||||||
|
@Post('/fix')
|
||||||
|
fixAuditFiles(@Body() dto: FileReportFixDto): Promise<void> {
|
||||||
|
return this.service.fixItems(dto.items);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import { AuditController } from 'src/controllers/audit.controller';
|
|||||||
import { AuthController } from 'src/controllers/auth.controller';
|
import { AuthController } from 'src/controllers/auth.controller';
|
||||||
import { DownloadController } from 'src/controllers/download.controller';
|
import { DownloadController } from 'src/controllers/download.controller';
|
||||||
import { FaceController } from 'src/controllers/face.controller';
|
import { FaceController } from 'src/controllers/face.controller';
|
||||||
|
import { ReportController } from 'src/controllers/file-report.controller';
|
||||||
import { JobController } from 'src/controllers/job.controller';
|
import { JobController } from 'src/controllers/job.controller';
|
||||||
import { LibraryController } from 'src/controllers/library.controller';
|
import { LibraryController } from 'src/controllers/library.controller';
|
||||||
import { MemoryController } from 'src/controllers/memory.controller';
|
import { MemoryController } from 'src/controllers/memory.controller';
|
||||||
@@ -20,19 +21,20 @@ import { SessionController } from 'src/controllers/session.controller';
|
|||||||
import { SharedLinkController } from 'src/controllers/shared-link.controller';
|
import { SharedLinkController } from 'src/controllers/shared-link.controller';
|
||||||
import { SyncController } from 'src/controllers/sync.controller';
|
import { SyncController } from 'src/controllers/sync.controller';
|
||||||
import { SystemConfigController } from 'src/controllers/system-config.controller';
|
import { SystemConfigController } from 'src/controllers/system-config.controller';
|
||||||
|
import { SystemMetadataController } from 'src/controllers/system-metadata.controller';
|
||||||
import { TagController } from 'src/controllers/tag.controller';
|
import { TagController } from 'src/controllers/tag.controller';
|
||||||
import { TimelineController } from 'src/controllers/timeline.controller';
|
import { TimelineController } from 'src/controllers/timeline.controller';
|
||||||
import { TrashController } from 'src/controllers/trash.controller';
|
import { TrashController } from 'src/controllers/trash.controller';
|
||||||
import { UserController } from 'src/controllers/user.controller';
|
import { UserController } from 'src/controllers/user.controller';
|
||||||
|
|
||||||
export const controllers = [
|
export const controllers = [
|
||||||
ActivityController,
|
|
||||||
AssetsController,
|
|
||||||
AssetControllerV1,
|
|
||||||
AssetController,
|
|
||||||
AppController,
|
|
||||||
AlbumController,
|
|
||||||
APIKeyController,
|
APIKeyController,
|
||||||
|
ActivityController,
|
||||||
|
AlbumController,
|
||||||
|
AppController,
|
||||||
|
AssetController,
|
||||||
|
AssetControllerV1,
|
||||||
|
AssetsController,
|
||||||
AuditController,
|
AuditController,
|
||||||
AuthController,
|
AuthController,
|
||||||
DownloadController,
|
DownloadController,
|
||||||
@@ -42,15 +44,17 @@ export const controllers = [
|
|||||||
MemoryController,
|
MemoryController,
|
||||||
OAuthController,
|
OAuthController,
|
||||||
PartnerController,
|
PartnerController,
|
||||||
|
PersonController,
|
||||||
|
ReportController,
|
||||||
SearchController,
|
SearchController,
|
||||||
ServerInfoController,
|
ServerInfoController,
|
||||||
SessionController,
|
SessionController,
|
||||||
SharedLinkController,
|
SharedLinkController,
|
||||||
SyncController,
|
SyncController,
|
||||||
SystemConfigController,
|
SystemConfigController,
|
||||||
|
SystemMetadataController,
|
||||||
TagController,
|
TagController,
|
||||||
TimelineController,
|
TimelineController,
|
||||||
TrashController,
|
TrashController,
|
||||||
UserController,
|
UserController,
|
||||||
PersonController,
|
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { Body, Controller, Get, HttpStatus, Post, Redirect, Req, Res } from '@nestjs/common';
|
import { Body, Controller, Get, HttpStatus, Post, Redirect, Req, Res } from '@nestjs/common';
|
||||||
import { ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
|
import { AuthType } from 'src/constants';
|
||||||
import {
|
import {
|
||||||
AuthDto,
|
AuthDto,
|
||||||
|
ImmichCookie,
|
||||||
LoginResponseDto,
|
LoginResponseDto,
|
||||||
OAuthAuthorizeResponseDto,
|
OAuthAuthorizeResponseDto,
|
||||||
OAuthCallbackDto,
|
OAuthCallbackDto,
|
||||||
@@ -11,6 +13,7 @@ import {
|
|||||||
import { UserResponseDto } from 'src/dtos/user.dto';
|
import { UserResponseDto } from 'src/dtos/user.dto';
|
||||||
import { Auth, Authenticated, GetLoginDetails, PublicRoute } from 'src/middleware/auth.guard';
|
import { Auth, Authenticated, GetLoginDetails, PublicRoute } from 'src/middleware/auth.guard';
|
||||||
import { AuthService, LoginDetails } from 'src/services/auth.service';
|
import { AuthService, LoginDetails } from 'src/services/auth.service';
|
||||||
|
import { respondWithCookie } from 'src/utils/response';
|
||||||
|
|
||||||
@ApiTags('OAuth')
|
@ApiTags('OAuth')
|
||||||
@Controller('oauth')
|
@Controller('oauth')
|
||||||
@@ -41,9 +44,15 @@ export class OAuthController {
|
|||||||
@Body() dto: OAuthCallbackDto,
|
@Body() dto: OAuthCallbackDto,
|
||||||
@GetLoginDetails() loginDetails: LoginDetails,
|
@GetLoginDetails() loginDetails: LoginDetails,
|
||||||
): Promise<LoginResponseDto> {
|
): Promise<LoginResponseDto> {
|
||||||
const { response, cookie } = await this.service.callback(dto, loginDetails);
|
const body = await this.service.callback(dto, loginDetails);
|
||||||
res.header('Set-Cookie', cookie);
|
return respondWithCookie(res, body, {
|
||||||
return response;
|
isSecure: loginDetails.isSecure,
|
||||||
|
values: [
|
||||||
|
{ key: ImmichCookie.ACCESS_TOKEN, value: body.accessToken },
|
||||||
|
{ key: ImmichCookie.AUTH_TYPE, value: AuthType.OAUTH },
|
||||||
|
{ key: ImmichCookie.IS_AUTHENTICATED, value: 'true' },
|
||||||
|
],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('link')
|
@Post('link')
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Controller, Get, HttpCode, HttpStatus, Post } from '@nestjs/common';
|
import { Controller, Get } from '@nestjs/common';
|
||||||
import { ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import {
|
import {
|
||||||
ServerConfigDto,
|
ServerConfigDto,
|
||||||
@@ -65,11 +65,4 @@ export class ServerInfoController {
|
|||||||
getSupportedMediaTypes(): ServerMediaTypesResponseDto {
|
getSupportedMediaTypes(): ServerMediaTypesResponseDto {
|
||||||
return this.service.getSupportedMediaTypes();
|
return this.service.getSupportedMediaTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@AdminRoute()
|
|
||||||
@Post('admin-onboarding')
|
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
|
||||||
setAdminOnboarding(): Promise<void> {
|
|
||||||
return this.service.setAdminOnboarding();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
import { Body, Controller, Delete, Get, Param, Patch, Post, Put, Query, Req, Res } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, Param, Patch, Post, Put, Query, Req, Res } from '@nestjs/common';
|
||||||
import { ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { IMMICH_SHARED_LINK_ACCESS_COOKIE } from 'src/constants';
|
|
||||||
import { AssetIdsResponseDto } from 'src/dtos/asset-ids.response.dto';
|
import { AssetIdsResponseDto } from 'src/dtos/asset-ids.response.dto';
|
||||||
import { AssetIdsDto } from 'src/dtos/asset.dto';
|
import { AssetIdsDto } from 'src/dtos/asset.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto, ImmichCookie } from 'src/dtos/auth.dto';
|
||||||
import {
|
import {
|
||||||
SharedLinkCreateDto,
|
SharedLinkCreateDto,
|
||||||
SharedLinkEditDto,
|
SharedLinkEditDto,
|
||||||
SharedLinkPasswordDto,
|
SharedLinkPasswordDto,
|
||||||
SharedLinkResponseDto,
|
SharedLinkResponseDto,
|
||||||
} from 'src/dtos/shared-link.dto';
|
} from 'src/dtos/shared-link.dto';
|
||||||
import { Auth, Authenticated, SharedLinkRoute } from 'src/middleware/auth.guard';
|
import { Auth, Authenticated, GetLoginDetails, SharedLinkRoute } from 'src/middleware/auth.guard';
|
||||||
|
import { LoginDetails } from 'src/services/auth.service';
|
||||||
import { SharedLinkService } from 'src/services/shared-link.service';
|
import { SharedLinkService } from 'src/services/shared-link.service';
|
||||||
|
import { respondWithCookie } from 'src/utils/response';
|
||||||
import { UUIDParamDto } from 'src/validation';
|
import { UUIDParamDto } from 'src/validation';
|
||||||
|
|
||||||
@ApiTags('Shared Link')
|
@ApiTags('Shared Link')
|
||||||
@@ -33,20 +34,17 @@ export class SharedLinkController {
|
|||||||
@Query() dto: SharedLinkPasswordDto,
|
@Query() dto: SharedLinkPasswordDto,
|
||||||
@Req() request: Request,
|
@Req() request: Request,
|
||||||
@Res({ passthrough: true }) res: Response,
|
@Res({ passthrough: true }) res: Response,
|
||||||
|
@GetLoginDetails() loginDetails: LoginDetails,
|
||||||
): Promise<SharedLinkResponseDto> {
|
): Promise<SharedLinkResponseDto> {
|
||||||
const sharedLinkToken = request.cookies?.[IMMICH_SHARED_LINK_ACCESS_COOKIE];
|
const sharedLinkToken = request.cookies?.[ImmichCookie.SHARED_LINK_TOKEN];
|
||||||
if (sharedLinkToken) {
|
if (sharedLinkToken) {
|
||||||
dto.token = sharedLinkToken;
|
dto.token = sharedLinkToken;
|
||||||
}
|
}
|
||||||
const response = await this.service.getMine(auth, dto);
|
const body = await this.service.getMine(auth, dto);
|
||||||
if (response.token) {
|
return respondWithCookie(res, body, {
|
||||||
res.cookie(IMMICH_SHARED_LINK_ACCESS_COOKIE, response.token, {
|
isSecure: loginDetails.isSecure,
|
||||||
expires: new Date(Date.now() + 1000 * 60 * 60 * 24),
|
values: body.token ? [{ key: ImmichCookie.SHARED_LINK_TOKEN, value: body.token }] : [],
|
||||||
httpOnly: true,
|
});
|
||||||
sameSite: 'lax',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { Body, Controller, Get, HttpCode, HttpStatus, Post } from '@nestjs/common';
|
||||||
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { AdminOnboardingUpdateDto, ReverseGeocodingStateResponseDto } from 'src/dtos/system-metadata.dto';
|
||||||
|
import { Authenticated } from 'src/middleware/auth.guard';
|
||||||
|
import { SystemMetadataService } from 'src/services/system-metadata.service';
|
||||||
|
|
||||||
|
@ApiTags('System Metadata')
|
||||||
|
@Controller('system-metadata')
|
||||||
|
@Authenticated({ admin: true })
|
||||||
|
export class SystemMetadataController {
|
||||||
|
constructor(private service: SystemMetadataService) {}
|
||||||
|
|
||||||
|
@Get('admin-onboarding')
|
||||||
|
getAdminOnboarding(): Promise<AdminOnboardingUpdateDto> {
|
||||||
|
return this.service.getAdminOnboarding();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('admin-onboarding')
|
||||||
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
|
updateAdminOnboarding(@Body() dto: AdminOnboardingUpdateDto): Promise<void> {
|
||||||
|
return this.service.updateAdminOnboarding(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('reverse-geocoding-state')
|
||||||
|
getReverseGeocodingState(): Promise<ReverseGeocodingStateResponseDto> {
|
||||||
|
return this.service.getReverseGeocodingState();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { randomUUID } from 'node:crypto';
|
||||||
import { dirname, join, resolve } from 'node:path';
|
import { dirname, join, resolve } from 'node:path';
|
||||||
import { APP_MEDIA_LOCATION } from 'src/constants';
|
import { APP_MEDIA_LOCATION } from 'src/constants';
|
||||||
import { SystemConfigCore } from 'src/cores/system-config.core';
|
import { SystemConfigCore } from 'src/cores/system-config.core';
|
||||||
@@ -308,4 +309,8 @@ export class StorageCore {
|
|||||||
static getNestedPath(folder: StorageFolder, ownerId: string, filename: string): string {
|
static getNestedPath(folder: StorageFolder, ownerId: string, filename: string): string {
|
||||||
return join(this.getNestedFolder(folder, ownerId, filename), filename);
|
return join(this.getNestedFolder(folder, ownerId, filename), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getTempPathInDir(dir: string): string {
|
||||||
|
return join(dir, `${randomUUID()}.tmp`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ export const defaults = Object.freeze<SystemConfig>({
|
|||||||
previewSize: 1440,
|
previewSize: 1440,
|
||||||
quality: 80,
|
quality: 80,
|
||||||
colorspace: Colorspace.P3,
|
colorspace: Colorspace.P3,
|
||||||
|
extractEmbedded: false,
|
||||||
},
|
},
|
||||||
newVersionCheck: {
|
newVersionCheck: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
|||||||
@@ -6,6 +6,25 @@ import { SessionEntity } from 'src/entities/session.entity';
|
|||||||
import { SharedLinkEntity } from 'src/entities/shared-link.entity';
|
import { SharedLinkEntity } from 'src/entities/shared-link.entity';
|
||||||
import { UserEntity } from 'src/entities/user.entity';
|
import { UserEntity } from 'src/entities/user.entity';
|
||||||
|
|
||||||
|
export enum ImmichCookie {
|
||||||
|
ACCESS_TOKEN = 'immich_access_token',
|
||||||
|
AUTH_TYPE = 'immich_auth_type',
|
||||||
|
IS_AUTHENTICATED = 'immich_is_authenticated',
|
||||||
|
SHARED_LINK_TOKEN = 'immich_shared_link_token',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ImmichHeader {
|
||||||
|
API_KEY = 'x-api-key',
|
||||||
|
USER_TOKEN = 'x-immich-user-token',
|
||||||
|
SESSION_TOKEN = 'x-immich-session-token',
|
||||||
|
SHARED_LINK_TOKEN = 'x-immich-share-key',
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CookieResponse = {
|
||||||
|
isSecure: boolean;
|
||||||
|
values: Array<{ key: ImmichCookie; value: string }>;
|
||||||
|
};
|
||||||
|
|
||||||
export class AuthDto {
|
export class AuthDto {
|
||||||
user!: UserEntity;
|
user!: UserEntity;
|
||||||
|
|
||||||
@@ -39,7 +58,7 @@ export class LoginResponseDto {
|
|||||||
|
|
||||||
export function mapLoginResponse(entity: UserEntity, accessToken: string): LoginResponseDto {
|
export function mapLoginResponse(entity: UserEntity, accessToken: string): LoginResponseDto {
|
||||||
return {
|
return {
|
||||||
accessToken: accessToken,
|
accessToken,
|
||||||
userId: entity.id,
|
userId: entity.id,
|
||||||
userEmail: entity.email,
|
userEmail: entity.email,
|
||||||
name: entity.name,
|
name: entity.name,
|
||||||
|
|||||||
@@ -417,6 +417,9 @@ class SystemConfigImageDto {
|
|||||||
@IsEnum(Colorspace)
|
@IsEnum(Colorspace)
|
||||||
@ApiProperty({ enumName: 'Colorspace', enum: Colorspace })
|
@ApiProperty({ enumName: 'Colorspace', enum: Colorspace })
|
||||||
colorspace!: Colorspace;
|
colorspace!: Colorspace;
|
||||||
|
|
||||||
|
@ValidateBoolean()
|
||||||
|
extractEmbedded!: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SystemConfigTrashDto {
|
class SystemConfigTrashDto {
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { IsBoolean } from 'class-validator';
|
||||||
|
|
||||||
|
export class AdminOnboardingUpdateDto {
|
||||||
|
@IsBoolean()
|
||||||
|
isOnboarded!: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AdminOnboardingResponseDto {
|
||||||
|
isOnboarded!: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ReverseGeocodingStateResponseDto {
|
||||||
|
lastUpdate!: string | null;
|
||||||
|
lastImportFileName!: string | null;
|
||||||
|
}
|
||||||
@@ -114,6 +114,7 @@ export const SystemConfigKey = {
|
|||||||
IMAGE_PREVIEW_SIZE: 'image.previewSize',
|
IMAGE_PREVIEW_SIZE: 'image.previewSize',
|
||||||
IMAGE_QUALITY: 'image.quality',
|
IMAGE_QUALITY: 'image.quality',
|
||||||
IMAGE_COLORSPACE: 'image.colorspace',
|
IMAGE_COLORSPACE: 'image.colorspace',
|
||||||
|
IMAGE_EXTRACT_EMBEDDED: 'image.extractEmbedded',
|
||||||
|
|
||||||
TRASH_ENABLED: 'trash.enabled',
|
TRASH_ENABLED: 'trash.enabled',
|
||||||
TRASH_DAYS: 'trash.days',
|
TRASH_DAYS: 'trash.days',
|
||||||
@@ -284,6 +285,7 @@ export interface SystemConfig {
|
|||||||
previewSize: number;
|
previewSize: number;
|
||||||
quality: number;
|
quality: number;
|
||||||
colorspace: Colorspace;
|
colorspace: Colorspace;
|
||||||
|
extractEmbedded: boolean;
|
||||||
};
|
};
|
||||||
newVersionCheck: {
|
newVersionCheck: {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ export interface VideoFormat {
|
|||||||
bitrate: number;
|
bitrate: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ImageDimensions {
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface VideoInfo {
|
export interface VideoInfo {
|
||||||
format: VideoFormat;
|
format: VideoFormat;
|
||||||
videoStreams: VideoStreamInfo[];
|
videoStreams: VideoStreamInfo[];
|
||||||
@@ -70,9 +75,11 @@ export interface VideoCodecHWConfig extends VideoCodecSWConfig {
|
|||||||
|
|
||||||
export interface IMediaRepository {
|
export interface IMediaRepository {
|
||||||
// image
|
// image
|
||||||
|
extract(input: string, output: string): Promise<boolean>;
|
||||||
resize(input: string | Buffer, output: string, options: ResizeOptions): Promise<void>;
|
resize(input: string | Buffer, output: string, options: ResizeOptions): Promise<void>;
|
||||||
crop(input: string, options: CropOptions): Promise<Buffer>;
|
crop(input: string, options: CropOptions): Promise<Buffer>;
|
||||||
generateThumbhash(imagePath: string): Promise<Buffer>;
|
generateThumbhash(imagePath: string): Promise<Buffer>;
|
||||||
|
getImageDimensions(input: string): Promise<ImageDimensions>;
|
||||||
|
|
||||||
// video
|
// video
|
||||||
probe(input: string): Promise<VideoInfo>;
|
probe(input: string): Promise<VideoInfo>;
|
||||||
|
|||||||
@@ -2,10 +2,12 @@ import { SessionEntity } from 'src/entities/session.entity';
|
|||||||
|
|
||||||
export const ISessionRepository = 'ISessionRepository';
|
export const ISessionRepository = 'ISessionRepository';
|
||||||
|
|
||||||
|
type E = SessionEntity;
|
||||||
|
|
||||||
export interface ISessionRepository {
|
export interface ISessionRepository {
|
||||||
create(dto: Partial<SessionEntity>): Promise<SessionEntity>;
|
create<T extends Partial<E>>(dto: T): Promise<T>;
|
||||||
update(dto: Partial<SessionEntity>): Promise<SessionEntity>;
|
update<T extends Partial<E>>(dto: T): Promise<T>;
|
||||||
delete(id: string): Promise<void>;
|
delete(id: string): Promise<void>;
|
||||||
getByToken(token: string): Promise<SessionEntity | null>;
|
getByToken(token: string): Promise<E | null>;
|
||||||
getByUserId(userId: string): Promise<SessionEntity[]>;
|
getByUserId(userId: string): Promise<E[]>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import {
|
|||||||
import { Reflector } from '@nestjs/core';
|
import { Reflector } from '@nestjs/core';
|
||||||
import { ApiBearerAuth, ApiCookieAuth, ApiOkResponse, ApiQuery, ApiSecurity } from '@nestjs/swagger';
|
import { ApiBearerAuth, ApiCookieAuth, ApiOkResponse, ApiQuery, ApiSecurity } from '@nestjs/swagger';
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
import { IMMICH_API_KEY_NAME } from 'src/constants';
|
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { ILoggerRepository } from 'src/interfaces/logger.interface';
|
import { ILoggerRepository } from 'src/interfaces/logger.interface';
|
||||||
import { AuthService, LoginDetails } from 'src/services/auth.service';
|
import { AuthService, LoginDetails } from 'src/services/auth.service';
|
||||||
@@ -21,6 +20,7 @@ export enum Metadata {
|
|||||||
ADMIN_ROUTE = 'admin_route',
|
ADMIN_ROUTE = 'admin_route',
|
||||||
SHARED_ROUTE = 'shared_route',
|
SHARED_ROUTE = 'shared_route',
|
||||||
PUBLIC_SECURITY = 'public_security',
|
PUBLIC_SECURITY = 'public_security',
|
||||||
|
API_KEY_SECURITY = 'api_key',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AuthenticatedOptions {
|
export interface AuthenticatedOptions {
|
||||||
@@ -32,7 +32,7 @@ export const Authenticated = (options: AuthenticatedOptions = {}) => {
|
|||||||
const decorators: MethodDecorator[] = [
|
const decorators: MethodDecorator[] = [
|
||||||
ApiBearerAuth(),
|
ApiBearerAuth(),
|
||||||
ApiCookieAuth(),
|
ApiCookieAuth(),
|
||||||
ApiSecurity(IMMICH_API_KEY_NAME),
|
ApiSecurity(Metadata.API_KEY_SECURITY),
|
||||||
SetMetadata(Metadata.AUTH_ROUTE, true),
|
SetMetadata(Metadata.AUTH_ROUTE, true),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
|
import { exiftool } from 'exiftool-vendored';
|
||||||
import ffmpeg, { FfprobeData } from 'fluent-ffmpeg';
|
import ffmpeg, { FfprobeData } from 'fluent-ffmpeg';
|
||||||
import fs from 'node:fs/promises';
|
import fs from 'node:fs/promises';
|
||||||
import { Writable } from 'node:stream';
|
import { Writable } from 'node:stream';
|
||||||
@@ -9,6 +10,7 @@ import { ILoggerRepository } from 'src/interfaces/logger.interface';
|
|||||||
import {
|
import {
|
||||||
CropOptions,
|
CropOptions,
|
||||||
IMediaRepository,
|
IMediaRepository,
|
||||||
|
ImageDimensions,
|
||||||
ResizeOptions,
|
ResizeOptions,
|
||||||
TranscodeOptions,
|
TranscodeOptions,
|
||||||
VideoInfo,
|
VideoInfo,
|
||||||
@@ -26,6 +28,23 @@ export class MediaRepository implements IMediaRepository {
|
|||||||
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
|
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
|
||||||
this.logger.setContext(MediaRepository.name);
|
this.logger.setContext(MediaRepository.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async extract(input: string, output: string): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
await exiftool.extractJpgFromRaw(input, output);
|
||||||
|
} catch (error: any) {
|
||||||
|
this.logger.debug('Could not extract JPEG from image, trying preview', error.message);
|
||||||
|
try {
|
||||||
|
await exiftool.extractPreview(input, output);
|
||||||
|
} catch (error: any) {
|
||||||
|
this.logger.debug('Could not extract preview from image', error.message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
crop(input: string | Buffer, options: CropOptions): Promise<Buffer> {
|
crop(input: string | Buffer, options: CropOptions): Promise<Buffer> {
|
||||||
return sharp(input, { failOn: 'none' })
|
return sharp(input, { failOn: 'none' })
|
||||||
.pipelineColorspace('rgb16')
|
.pipelineColorspace('rgb16')
|
||||||
@@ -133,6 +152,11 @@ export class MediaRepository implements IMediaRepository {
|
|||||||
return Buffer.from(thumbhash.rgbaToThumbHash(info.width, info.height, data));
|
return Buffer.from(thumbhash.rgbaToThumbHash(info.width, info.height, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getImageDimensions(input: string): Promise<ImageDimensions> {
|
||||||
|
const { width = 0, height = 0 } = await sharp(input).metadata();
|
||||||
|
return { width, height };
|
||||||
|
}
|
||||||
|
|
||||||
private configureFfmpegCall(input: string, output: string | Writable, options: TranscodeOptions) {
|
private configureFfmpegCall(input: string, output: string | Writable, options: TranscodeOptions) {
|
||||||
return ffmpeg(input, { niceness: 10 })
|
return ffmpeg(input, { niceness: 10 })
|
||||||
.inputOptions(options.inputOptions)
|
.inputOptions(options.inputOptions)
|
||||||
@@ -140,9 +164,4 @@ export class MediaRepository implements IMediaRepository {
|
|||||||
.output(output)
|
.output(output)
|
||||||
.on('error', (error, stdout, stderr) => this.logger.error(stderr || error));
|
.on('error', (error, stdout, stderr) => this.logger.error(stderr || error));
|
||||||
}
|
}
|
||||||
|
|
||||||
private chainPath(existing: string, path: string) {
|
|
||||||
const separator = existing.endsWith(':') ? '' : ':';
|
|
||||||
return `${existing}${separator}${path}`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ export class MetadataRepository implements IMetadataRepository {
|
|||||||
this.logger.log('Initializing metadata repository');
|
this.logger.log('Initializing metadata repository');
|
||||||
const geodataDate = await readFile(geodataDatePath, 'utf8');
|
const geodataDate = await readFile(geodataDatePath, 'utf8');
|
||||||
|
|
||||||
|
// TODO move to metadata service init
|
||||||
const geocodingMetadata = await this.systemMetadataRepository.get(SystemMetadataKey.REVERSE_GEOCODING_STATE);
|
const geocodingMetadata = await this.systemMetadataRepository.get(SystemMetadataKey.REVERSE_GEOCODING_STATE);
|
||||||
|
|
||||||
if (geocodingMetadata?.lastUpdate === geodataDate) {
|
if (geocodingMetadata?.lastUpdate === geodataDate) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,12 +31,12 @@ export class SessionRepository implements ISessionRepository {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
create(session: Partial<SessionEntity>): Promise<SessionEntity> {
|
create<T extends Partial<SessionEntity>>(dto: T): Promise<T & { id: string }> {
|
||||||
return this.repository.save(session);
|
return this.repository.save(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
update(session: Partial<SessionEntity>): Promise<SessionEntity> {
|
update<T extends Partial<SessionEntity>>(dto: T): Promise<T> {
|
||||||
return this.repository.save(session);
|
return this.repository.save(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GenerateSql({ params: [DummyValue.UUID] })
|
@GenerateSql({ params: [DummyValue.UUID] })
|
||||||
|
|||||||
@@ -143,20 +143,6 @@ describe('AuthService', () => {
|
|||||||
await expect(sut.login(fixtures.login, loginDetails)).resolves.toEqual(loginResponseStub.user1password);
|
await expect(sut.login(fixtures.login, loginDetails)).resolves.toEqual(loginResponseStub.user1password);
|
||||||
expect(userMock.getByEmail).toHaveBeenCalledTimes(1);
|
expect(userMock.getByEmail).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate the cookie headers (insecure)', async () => {
|
|
||||||
userMock.getByEmail.mockResolvedValue(userStub.user1);
|
|
||||||
sessionMock.create.mockResolvedValue(sessionStub.valid);
|
|
||||||
await expect(
|
|
||||||
sut.login(fixtures.login, {
|
|
||||||
clientIp: '127.0.0.1',
|
|
||||||
isSecure: false,
|
|
||||||
deviceOS: '',
|
|
||||||
deviceType: '',
|
|
||||||
}),
|
|
||||||
).resolves.toEqual(loginResponseStub.user1insecure);
|
|
||||||
expect(userMock.getByEmail).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('changePassword', () => {
|
describe('changePassword', () => {
|
||||||
@@ -354,10 +340,7 @@ describe('AuthService', () => {
|
|||||||
sessionMock.getByToken.mockResolvedValue(sessionStub.inactive);
|
sessionMock.getByToken.mockResolvedValue(sessionStub.inactive);
|
||||||
sessionMock.update.mockResolvedValue(sessionStub.valid);
|
sessionMock.update.mockResolvedValue(sessionStub.valid);
|
||||||
const headers: IncomingHttpHeaders = { cookie: 'immich_access_token=auth_token' };
|
const headers: IncomingHttpHeaders = { cookie: 'immich_access_token=auth_token' };
|
||||||
await expect(sut.validate(headers, {})).resolves.toEqual({
|
await expect(sut.validate(headers, {})).resolves.toBeDefined();
|
||||||
user: userStub.user1,
|
|
||||||
session: sessionStub.valid,
|
|
||||||
});
|
|
||||||
expect(sessionMock.update.mock.calls[0][0]).toMatchObject({ id: 'not_active', updatedAt: expect.any(Date) });
|
expect(sessionMock.update.mock.calls[0][0]).toMatchObject({ id: 'not_active', updatedAt: expect.any(Date) });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,23 +10,16 @@ import cookieParser from 'cookie';
|
|||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { IncomingHttpHeaders } from 'node:http';
|
import { IncomingHttpHeaders } from 'node:http';
|
||||||
import { ClientMetadata, Issuer, UserinfoResponse, custom, generators } from 'openid-client';
|
import { ClientMetadata, Issuer, UserinfoResponse, custom, generators } from 'openid-client';
|
||||||
import {
|
import { AuthType, LOGIN_URL, MOBILE_REDIRECT } from 'src/constants';
|
||||||
AuthType,
|
|
||||||
IMMICH_ACCESS_COOKIE,
|
|
||||||
IMMICH_API_KEY_HEADER,
|
|
||||||
IMMICH_AUTH_TYPE_COOKIE,
|
|
||||||
IMMICH_IS_AUTHENTICATED,
|
|
||||||
LOGIN_URL,
|
|
||||||
MOBILE_REDIRECT,
|
|
||||||
} from 'src/constants';
|
|
||||||
import { AccessCore } from 'src/cores/access.core';
|
import { AccessCore } from 'src/cores/access.core';
|
||||||
import { SystemConfigCore } from 'src/cores/system-config.core';
|
import { SystemConfigCore } from 'src/cores/system-config.core';
|
||||||
import { UserCore } from 'src/cores/user.core';
|
import { UserCore } from 'src/cores/user.core';
|
||||||
import {
|
import {
|
||||||
AuthDto,
|
AuthDto,
|
||||||
ChangePasswordDto,
|
ChangePasswordDto,
|
||||||
|
ImmichCookie,
|
||||||
|
ImmichHeader,
|
||||||
LoginCredentialDto,
|
LoginCredentialDto,
|
||||||
LoginResponseDto,
|
|
||||||
LogoutResponseDto,
|
LogoutResponseDto,
|
||||||
OAuthAuthorizeResponseDto,
|
OAuthAuthorizeResponseDto,
|
||||||
OAuthCallbackDto,
|
OAuthCallbackDto,
|
||||||
@@ -55,11 +48,6 @@ export interface LoginDetails {
|
|||||||
deviceOS: string;
|
deviceOS: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LoginResponse {
|
|
||||||
response: LoginResponseDto;
|
|
||||||
cookie: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface OAuthProfile extends UserinfoResponse {
|
interface OAuthProfile extends UserinfoResponse {
|
||||||
email: string;
|
email: string;
|
||||||
}
|
}
|
||||||
@@ -95,7 +83,7 @@ export class AuthService {
|
|||||||
custom.setHttpOptionsDefaults({ timeout: 30_000 });
|
custom.setHttpOptionsDefaults({ timeout: 30_000 });
|
||||||
}
|
}
|
||||||
|
|
||||||
async login(dto: LoginCredentialDto, details: LoginDetails): Promise<LoginResponse> {
|
async login(dto: LoginCredentialDto, details: LoginDetails) {
|
||||||
const config = await this.configCore.getConfig();
|
const config = await this.configCore.getConfig();
|
||||||
if (!config.passwordLogin.enabled) {
|
if (!config.passwordLogin.enabled) {
|
||||||
throw new UnauthorizedException('Password login has been disabled');
|
throw new UnauthorizedException('Password login has been disabled');
|
||||||
@@ -114,7 +102,7 @@ export class AuthService {
|
|||||||
throw new UnauthorizedException('Incorrect email or password');
|
throw new UnauthorizedException('Incorrect email or password');
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.createLoginResponse(user, AuthType.PASSWORD, details);
|
return this.createLoginResponse(user, details);
|
||||||
}
|
}
|
||||||
|
|
||||||
async logout(auth: AuthDto, authType: AuthType): Promise<LogoutResponseDto> {
|
async logout(auth: AuthDto, authType: AuthType): Promise<LogoutResponseDto> {
|
||||||
@@ -161,13 +149,13 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async validate(headers: IncomingHttpHeaders, params: Record<string, string>): Promise<AuthDto> {
|
async validate(headers: IncomingHttpHeaders, params: Record<string, string>): Promise<AuthDto> {
|
||||||
const shareKey = (headers['x-immich-share-key'] || params.key) as string;
|
const shareKey = (headers[ImmichHeader.SHARED_LINK_TOKEN] || params.key) as string;
|
||||||
const session = (headers['x-immich-user-token'] ||
|
const session = (headers[ImmichHeader.USER_TOKEN] ||
|
||||||
headers['x-immich-session-token'] ||
|
headers[ImmichHeader.SESSION_TOKEN] ||
|
||||||
params.sessionKey ||
|
params.sessionKey ||
|
||||||
this.getBearerToken(headers) ||
|
this.getBearerToken(headers) ||
|
||||||
this.getCookieToken(headers)) as string;
|
this.getCookieToken(headers)) as string;
|
||||||
const apiKey = (headers[IMMICH_API_KEY_HEADER] || params.apiKey) as string;
|
const apiKey = (headers[ImmichHeader.API_KEY] || params.apiKey) as string;
|
||||||
|
|
||||||
if (shareKey) {
|
if (shareKey) {
|
||||||
return this.validateSharedLink(shareKey);
|
return this.validateSharedLink(shareKey);
|
||||||
@@ -204,10 +192,7 @@ export class AuthService {
|
|||||||
return { url };
|
return { url };
|
||||||
}
|
}
|
||||||
|
|
||||||
async callback(
|
async callback(dto: OAuthCallbackDto, loginDetails: LoginDetails) {
|
||||||
dto: OAuthCallbackDto,
|
|
||||||
loginDetails: LoginDetails,
|
|
||||||
): Promise<{ response: LoginResponseDto; cookie: string[] }> {
|
|
||||||
const config = await this.configCore.getConfig();
|
const config = await this.configCore.getConfig();
|
||||||
const profile = await this.getOAuthProfile(config, dto.url);
|
const profile = await this.getOAuthProfile(config, dto.url);
|
||||||
this.logger.debug(`Logging in with OAuth: ${JSON.stringify(profile)}`);
|
this.logger.debug(`Logging in with OAuth: ${JSON.stringify(profile)}`);
|
||||||
@@ -256,7 +241,7 @@ export class AuthService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.createLoginResponse(user, AuthType.OAUTH, loginDetails);
|
return this.createLoginResponse(user, loginDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
async link(auth: AuthDto, dto: OAuthCallbackDto): Promise<UserResponseDto> {
|
async link(auth: AuthDto, dto: OAuthCallbackDto): Promise<UserResponseDto> {
|
||||||
@@ -353,7 +338,7 @@ export class AuthService {
|
|||||||
|
|
||||||
private getCookieToken(headers: IncomingHttpHeaders): string | null {
|
private getCookieToken(headers: IncomingHttpHeaders): string | null {
|
||||||
const cookies = cookieParser.parse(headers.cookie || '');
|
const cookies = cookieParser.parse(headers.cookie || '');
|
||||||
return cookies[IMMICH_ACCESS_COOKIE] || null;
|
return cookies[ImmichCookie.ACCESS_TOKEN] || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async validateSharedLink(key: string | string[]): Promise<AuthDto> {
|
async validateSharedLink(key: string | string[]): Promise<AuthDto> {
|
||||||
@@ -389,14 +374,14 @@ export class AuthService {
|
|||||||
|
|
||||||
private async validateSession(tokenValue: string): Promise<AuthDto> {
|
private async validateSession(tokenValue: string): Promise<AuthDto> {
|
||||||
const hashedToken = this.cryptoRepository.hashSha256(tokenValue);
|
const hashedToken = this.cryptoRepository.hashSha256(tokenValue);
|
||||||
let session = await this.sessionRepository.getByToken(hashedToken);
|
const session = await this.sessionRepository.getByToken(hashedToken);
|
||||||
|
|
||||||
if (session?.user) {
|
if (session?.user) {
|
||||||
const now = DateTime.now();
|
const now = DateTime.now();
|
||||||
const updatedAt = DateTime.fromJSDate(session.updatedAt);
|
const updatedAt = DateTime.fromJSDate(session.updatedAt);
|
||||||
const diff = now.diff(updatedAt, ['hours']);
|
const diff = now.diff(updatedAt, ['hours']);
|
||||||
if (diff.hours > 1) {
|
if (diff.hours > 1) {
|
||||||
session = await this.sessionRepository.update({ id: session.id, updatedAt: new Date() });
|
await this.sessionRepository.update({ id: session.id, updatedAt: new Date() });
|
||||||
}
|
}
|
||||||
|
|
||||||
return { user: session.user, session: session };
|
return { user: session.user, session: session };
|
||||||
@@ -405,7 +390,7 @@ export class AuthService {
|
|||||||
throw new UnauthorizedException('Invalid user token');
|
throw new UnauthorizedException('Invalid user token');
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createLoginResponse(user: UserEntity, authType: AuthType, loginDetails: LoginDetails) {
|
private async createLoginResponse(user: UserEntity, loginDetails: LoginDetails) {
|
||||||
const key = this.cryptoRepository.newPassword(32);
|
const key = this.cryptoRepository.newPassword(32);
|
||||||
const token = this.cryptoRepository.hashSha256(key);
|
const token = this.cryptoRepository.hashSha256(key);
|
||||||
|
|
||||||
@@ -416,28 +401,7 @@ export class AuthService {
|
|||||||
deviceType: loginDetails.deviceType,
|
deviceType: loginDetails.deviceType,
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = mapLoginResponse(user, key);
|
return mapLoginResponse(user, key);
|
||||||
const cookie = this.getCookies(response, authType, loginDetails);
|
|
||||||
return { response, cookie };
|
|
||||||
}
|
|
||||||
|
|
||||||
private getCookies(loginResponse: LoginResponseDto, authType: AuthType, { isSecure }: LoginDetails) {
|
|
||||||
const maxAge = 400 * 24 * 3600; // 400 days
|
|
||||||
|
|
||||||
let authTypeCookie = '';
|
|
||||||
let accessTokenCookie = '';
|
|
||||||
let isAuthenticatedCookie = '';
|
|
||||||
|
|
||||||
if (isSecure) {
|
|
||||||
accessTokenCookie = `${IMMICH_ACCESS_COOKIE}=${loginResponse.accessToken}; HttpOnly; Secure; Path=/; Max-Age=${maxAge}; SameSite=Lax;`;
|
|
||||||
authTypeCookie = `${IMMICH_AUTH_TYPE_COOKIE}=${authType}; HttpOnly; Secure; Path=/; Max-Age=${maxAge}; SameSite=Lax;`;
|
|
||||||
isAuthenticatedCookie = `${IMMICH_IS_AUTHENTICATED}=true; Secure; Path=/; Max-Age=${maxAge}; SameSite=Lax;`;
|
|
||||||
} else {
|
|
||||||
accessTokenCookie = `${IMMICH_ACCESS_COOKIE}=${loginResponse.accessToken}; HttpOnly; Path=/; Max-Age=${maxAge}; SameSite=Lax;`;
|
|
||||||
authTypeCookie = `${IMMICH_AUTH_TYPE_COOKIE}=${authType}; HttpOnly; Path=/; Max-Age=${maxAge}; SameSite=Lax;`;
|
|
||||||
isAuthenticatedCookie = `${IMMICH_IS_AUTHENTICATED}=true; Path=/; Max-Age=${maxAge}; SameSite=Lax;`;
|
|
||||||
}
|
|
||||||
return [accessTokenCookie, authTypeCookie, isAuthenticatedCookie];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private getClaim<T>(profile: OAuthProfile, options: ClaimOptions<T>): T {
|
private getClaim<T>(profile: OAuthProfile, options: ClaimOptions<T>): T {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import { StorageTemplateService } from 'src/services/storage-template.service';
|
|||||||
import { StorageService } from 'src/services/storage.service';
|
import { StorageService } from 'src/services/storage.service';
|
||||||
import { SyncService } from 'src/services/sync.service';
|
import { SyncService } from 'src/services/sync.service';
|
||||||
import { SystemConfigService } from 'src/services/system-config.service';
|
import { SystemConfigService } from 'src/services/system-config.service';
|
||||||
|
import { SystemMetadataService } from 'src/services/system-metadata.service';
|
||||||
import { TagService } from 'src/services/tag.service';
|
import { TagService } from 'src/services/tag.service';
|
||||||
import { TimelineService } from 'src/services/timeline.service';
|
import { TimelineService } from 'src/services/timeline.service';
|
||||||
import { TrashService } from 'src/services/trash.service';
|
import { TrashService } from 'src/services/trash.service';
|
||||||
@@ -58,6 +59,7 @@ export const services = [
|
|||||||
StorageTemplateService,
|
StorageTemplateService,
|
||||||
SyncService,
|
SyncService,
|
||||||
SystemConfigService,
|
SystemConfigService,
|
||||||
|
SystemMetadataService,
|
||||||
TagService,
|
TagService,
|
||||||
TimelineService,
|
TimelineService,
|
||||||
TrashService,
|
TrashService,
|
||||||
|
|||||||
@@ -393,14 +393,12 @@ describe(MediaService.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should generate a P3 thumbnail for a wide gamut image', async () => {
|
it('should generate a P3 thumbnail for a wide gamut image', async () => {
|
||||||
assetMock.getByIds.mockResolvedValue([
|
assetMock.getByIds.mockResolvedValue([assetStub.imageDng]);
|
||||||
{ ...assetStub.image, exifInfo: { profileDescription: 'Adobe RGB', bitsPerSample: 14 } as ExifEntity },
|
|
||||||
]);
|
|
||||||
await sut.handleGenerateThumbnail({ id: assetStub.image.id });
|
await sut.handleGenerateThumbnail({ id: assetStub.image.id });
|
||||||
|
|
||||||
expect(storageMock.mkdirSync).toHaveBeenCalledWith('upload/thumbs/user-id/as/se');
|
expect(storageMock.mkdirSync).toHaveBeenCalledWith('upload/thumbs/user-id/as/se');
|
||||||
expect(mediaMock.resize).toHaveBeenCalledWith(
|
expect(mediaMock.resize).toHaveBeenCalledWith(
|
||||||
'/original/path.jpg',
|
assetStub.imageDng.originalPath,
|
||||||
'upload/thumbs/user-id/as/se/asset-id-thumbnail.webp',
|
'upload/thumbs/user-id/as/se/asset-id-thumbnail.webp',
|
||||||
{
|
{
|
||||||
format: ImageFormat.WEBP,
|
format: ImageFormat.WEBP,
|
||||||
@@ -415,7 +413,96 @@ describe(MediaService.name, () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('handleGenerateThumbhashThumbnail', () => {
|
it('should extract embedded image if enabled and available', async () => {
|
||||||
|
mediaMock.extract.mockResolvedValue(true);
|
||||||
|
mediaMock.getImageDimensions.mockResolvedValue({ width: 3840, height: 2160 });
|
||||||
|
configMock.load.mockResolvedValue([{ key: SystemConfigKey.IMAGE_EXTRACT_EMBEDDED, value: true }]);
|
||||||
|
assetMock.getByIds.mockResolvedValue([assetStub.imageDng]);
|
||||||
|
|
||||||
|
await sut.handleGenerateThumbnail({ id: assetStub.image.id });
|
||||||
|
|
||||||
|
const extractedPath = mediaMock.extract.mock.calls.at(-1)?.[1].toString();
|
||||||
|
expect(mediaMock.resize.mock.calls).toEqual([
|
||||||
|
[
|
||||||
|
extractedPath,
|
||||||
|
'upload/thumbs/user-id/as/se/asset-id-thumbnail.webp',
|
||||||
|
{
|
||||||
|
format: ImageFormat.WEBP,
|
||||||
|
size: 250,
|
||||||
|
quality: 80,
|
||||||
|
colorspace: Colorspace.P3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
expect(extractedPath?.endsWith('.tmp')).toBe(true);
|
||||||
|
expect(storageMock.unlink).toHaveBeenCalledWith(extractedPath);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resize original image if embedded image is too small', async () => {
|
||||||
|
mediaMock.extract.mockResolvedValue(true);
|
||||||
|
mediaMock.getImageDimensions.mockResolvedValue({ width: 1000, height: 1000 });
|
||||||
|
configMock.load.mockResolvedValue([{ key: SystemConfigKey.IMAGE_EXTRACT_EMBEDDED, value: true }]);
|
||||||
|
assetMock.getByIds.mockResolvedValue([assetStub.imageDng]);
|
||||||
|
|
||||||
|
await sut.handleGenerateThumbnail({ id: assetStub.image.id });
|
||||||
|
|
||||||
|
expect(mediaMock.resize.mock.calls).toEqual([
|
||||||
|
[
|
||||||
|
assetStub.imageDng.originalPath,
|
||||||
|
'upload/thumbs/user-id/as/se/asset-id-thumbnail.webp',
|
||||||
|
{
|
||||||
|
format: ImageFormat.WEBP,
|
||||||
|
size: 250,
|
||||||
|
quality: 80,
|
||||||
|
colorspace: Colorspace.P3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
const extractedPath = mediaMock.extract.mock.calls.at(-1)?.[1].toString();
|
||||||
|
expect(extractedPath?.endsWith('.tmp')).toBe(true);
|
||||||
|
expect(storageMock.unlink).toHaveBeenCalledWith(extractedPath);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resize original image if embedded image not found', async () => {
|
||||||
|
configMock.load.mockResolvedValue([{ key: SystemConfigKey.IMAGE_EXTRACT_EMBEDDED, value: true }]);
|
||||||
|
assetMock.getByIds.mockResolvedValue([assetStub.imageDng]);
|
||||||
|
|
||||||
|
await sut.handleGenerateThumbnail({ id: assetStub.image.id });
|
||||||
|
|
||||||
|
expect(mediaMock.resize).toHaveBeenCalledWith(
|
||||||
|
assetStub.imageDng.originalPath,
|
||||||
|
'upload/thumbs/user-id/as/se/asset-id-thumbnail.webp',
|
||||||
|
{
|
||||||
|
format: ImageFormat.WEBP,
|
||||||
|
size: 250,
|
||||||
|
quality: 80,
|
||||||
|
colorspace: Colorspace.P3,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
expect(mediaMock.getImageDimensions).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resize original image if embedded image extraction is not enabled', async () => {
|
||||||
|
configMock.load.mockResolvedValue([{ key: SystemConfigKey.IMAGE_EXTRACT_EMBEDDED, value: false }]);
|
||||||
|
assetMock.getByIds.mockResolvedValue([assetStub.imageDng]);
|
||||||
|
|
||||||
|
await sut.handleGenerateThumbnail({ id: assetStub.image.id });
|
||||||
|
|
||||||
|
expect(mediaMock.extract).not.toHaveBeenCalled();
|
||||||
|
expect(mediaMock.resize).toHaveBeenCalledWith(
|
||||||
|
assetStub.imageDng.originalPath,
|
||||||
|
'upload/thumbs/user-id/as/se/asset-id-thumbnail.webp',
|
||||||
|
{
|
||||||
|
format: ImageFormat.WEBP,
|
||||||
|
size: 250,
|
||||||
|
quality: 80,
|
||||||
|
colorspace: Colorspace.P3,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
expect(mediaMock.getImageDimensions).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('handleGenerateThumbhash', () => {
|
||||||
it('should skip thumbhash generation if asset not found', async () => {
|
it('should skip thumbhash generation if asset not found', async () => {
|
||||||
assetMock.getByIds.mockResolvedValue([]);
|
assetMock.getByIds.mockResolvedValue([]);
|
||||||
await sut.handleGenerateThumbhash({ id: assetStub.image.id });
|
await sut.handleGenerateThumbhash({ id: assetStub.image.id });
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Inject, Injectable, UnsupportedMediaTypeException } from '@nestjs/common';
|
import { Inject, Injectable, UnsupportedMediaTypeException } from '@nestjs/common';
|
||||||
|
import { dirname } from 'node:path';
|
||||||
import { GeneratedImageType, StorageCore, StorageFolder } from 'src/cores/storage.core';
|
import { GeneratedImageType, StorageCore, StorageFolder } from 'src/cores/storage.core';
|
||||||
import { SystemConfigCore } from 'src/cores/system-config.core';
|
import { SystemConfigCore } from 'src/cores/system-config.core';
|
||||||
import { SystemConfigFFmpegDto } from 'src/dtos/system-config.dto';
|
import { SystemConfigFFmpegDto } from 'src/dtos/system-config.dto';
|
||||||
@@ -42,6 +43,7 @@ import {
|
|||||||
VAAPIConfig,
|
VAAPIConfig,
|
||||||
VP9Config,
|
VP9Config,
|
||||||
} from 'src/utils/media';
|
} from 'src/utils/media';
|
||||||
|
import { mimeTypes } from 'src/utils/mime-types';
|
||||||
import { usePagination } from 'src/utils/pagination';
|
import { usePagination } from 'src/utils/pagination';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -195,9 +197,21 @@ export class MediaService {
|
|||||||
|
|
||||||
switch (asset.type) {
|
switch (asset.type) {
|
||||||
case AssetType.IMAGE: {
|
case AssetType.IMAGE: {
|
||||||
const colorspace = this.isSRGB(asset) ? Colorspace.SRGB : image.colorspace;
|
const shouldExtract = image.extractEmbedded && mimeTypes.isRaw(asset.originalPath);
|
||||||
const imageOptions = { format, size, colorspace, quality: image.quality };
|
const extractedPath = StorageCore.getTempPathInDir(dirname(path));
|
||||||
await this.mediaRepository.resize(asset.originalPath, path, imageOptions);
|
const didExtract = shouldExtract && (await this.mediaRepository.extract(asset.originalPath, extractedPath));
|
||||||
|
|
||||||
|
try {
|
||||||
|
const useExtracted = didExtract && (await this.shouldUseExtractedImage(extractedPath, image.previewSize));
|
||||||
|
const colorspace = this.isSRGB(asset) ? Colorspace.SRGB : image.colorspace;
|
||||||
|
const imageOptions = { format, size, colorspace, quality: image.quality };
|
||||||
|
|
||||||
|
await this.mediaRepository.resize(useExtracted ? extractedPath : asset.originalPath, path, imageOptions);
|
||||||
|
} finally {
|
||||||
|
if (didExtract) {
|
||||||
|
await this.storageRepository.unlink(extractedPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,7 +541,7 @@ export class MediaService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parseBitrateToBps(bitrateString: string) {
|
private parseBitrateToBps(bitrateString: string) {
|
||||||
const bitrateValue = Number.parseInt(bitrateString);
|
const bitrateValue = Number.parseInt(bitrateString);
|
||||||
|
|
||||||
if (Number.isNaN(bitrateValue)) {
|
if (Number.isNaN(bitrateValue)) {
|
||||||
@@ -542,4 +556,11 @@ export class MediaService {
|
|||||||
return bitrateValue;
|
return bitrateValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async shouldUseExtractedImage(extractedPath: string, targetSize: number) {
|
||||||
|
const { width, height } = await this.mediaRepository.getImageDimensions(extractedPath);
|
||||||
|
const extractedSize = Math.min(width, height);
|
||||||
|
|
||||||
|
return extractedSize >= targetSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { serverVersion } from 'src/constants';
|
import { serverVersion } from 'src/constants';
|
||||||
import { SystemMetadataKey } from 'src/entities/system-metadata.entity';
|
|
||||||
import { IEventRepository } from 'src/interfaces/event.interface';
|
import { IEventRepository } from 'src/interfaces/event.interface';
|
||||||
import { ILoggerRepository } from 'src/interfaces/logger.interface';
|
import { ILoggerRepository } from 'src/interfaces/logger.interface';
|
||||||
import { IServerInfoRepository } from 'src/interfaces/server-info.interface';
|
import { IServerInfoRepository } from 'src/interfaces/server-info.interface';
|
||||||
@@ -207,13 +206,6 @@ describe(ServerInfoService.name, () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setAdminOnboarding', () => {
|
|
||||||
it('should set admin onboarding to true', async () => {
|
|
||||||
await sut.setAdminOnboarding();
|
|
||||||
expect(systemMetadataMock.set).toHaveBeenCalledWith(SystemMetadataKey.ADMIN_ONBOARDING, { isOnboarded: true });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getStats', () => {
|
describe('getStats', () => {
|
||||||
it('should total up usage by user', async () => {
|
it('should total up usage by user', async () => {
|
||||||
userMock.getUserStats.mockResolvedValue([
|
userMock.getUserStats.mockResolvedValue([
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ export class ServerInfoService {
|
|||||||
|
|
||||||
const featureFlags = await this.getFeatures();
|
const featureFlags = await this.getFeatures();
|
||||||
if (featureFlags.configFile) {
|
if (featureFlags.configFile) {
|
||||||
await this.setAdminOnboarding();
|
await this.systemMetadataRepository.set(SystemMetadataKey.ADMIN_ONBOARDING, {
|
||||||
|
isOnboarded: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,10 +107,6 @@ export class ServerInfoService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
setAdminOnboarding(): Promise<void> {
|
|
||||||
return this.systemMetadataRepository.set(SystemMetadataKey.ADMIN_ONBOARDING, { isOnboarded: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
async getStatistics(): Promise<ServerStatsResponseDto> {
|
async getStatistics(): Promise<ServerStatsResponseDto> {
|
||||||
const userStats: UserStatsQueryResponse[] = await this.userRepository.getUserStats();
|
const userStats: UserStatsQueryResponse[] = await this.userRepository.getUserStats();
|
||||||
const serverStats = new ServerStatsResponseDto();
|
const serverStats = new ServerStatsResponseDto();
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ const updatedConfig = Object.freeze<SystemConfig>({
|
|||||||
previewSize: 1440,
|
previewSize: 1440,
|
||||||
quality: 80,
|
quality: 80,
|
||||||
colorspace: Colorspace.P3,
|
colorspace: Colorspace.P3,
|
||||||
|
extractEmbedded: false,
|
||||||
},
|
},
|
||||||
newVersionCheck: {
|
newVersionCheck: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { SystemMetadataKey } from 'src/entities/system-metadata.entity';
|
||||||
|
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
|
||||||
|
import { SystemMetadataService } from 'src/services/system-metadata.service';
|
||||||
|
import { newSystemMetadataRepositoryMock } from 'test/repositories/system-metadata.repository.mock';
|
||||||
|
import { Mocked } from 'vitest';
|
||||||
|
|
||||||
|
describe(SystemMetadataService.name, () => {
|
||||||
|
let sut: SystemMetadataService;
|
||||||
|
let metadataMock: Mocked<ISystemMetadataRepository>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
metadataMock = newSystemMetadataRepositoryMock();
|
||||||
|
sut = new SystemMetadataService(metadataMock);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work', () => {
|
||||||
|
expect(sut).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('updateAdminOnboarding', () => {
|
||||||
|
it('should update isOnboarded to true', async () => {
|
||||||
|
await expect(sut.updateAdminOnboarding({ isOnboarded: true })).resolves.toBeUndefined();
|
||||||
|
expect(metadataMock.set).toHaveBeenCalledWith(SystemMetadataKey.ADMIN_ONBOARDING, { isOnboarded: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update isOnboarded to false', async () => {
|
||||||
|
await expect(sut.updateAdminOnboarding({ isOnboarded: false })).resolves.toBeUndefined();
|
||||||
|
expect(metadataMock.set).toHaveBeenCalledWith(SystemMetadataKey.ADMIN_ONBOARDING, { isOnboarded: false });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
|
import {
|
||||||
|
AdminOnboardingResponseDto,
|
||||||
|
AdminOnboardingUpdateDto,
|
||||||
|
ReverseGeocodingStateResponseDto,
|
||||||
|
} from 'src/dtos/system-metadata.dto';
|
||||||
|
import { SystemMetadataKey } from 'src/entities/system-metadata.entity';
|
||||||
|
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SystemMetadataService {
|
||||||
|
constructor(@Inject(ISystemMetadataRepository) private repository: ISystemMetadataRepository) {}
|
||||||
|
|
||||||
|
async getAdminOnboarding(): Promise<AdminOnboardingResponseDto> {
|
||||||
|
const value = await this.repository.get(SystemMetadataKey.ADMIN_ONBOARDING);
|
||||||
|
return { isOnboarded: false, ...value };
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateAdminOnboarding(dto: AdminOnboardingUpdateDto): Promise<void> {
|
||||||
|
await this.repository.set(SystemMetadataKey.ADMIN_ONBOARDING, {
|
||||||
|
isOnboarded: dto.isOnboarded,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getReverseGeocodingState(): Promise<ReverseGeocodingStateResponseDto> {
|
||||||
|
const value = await this.repository.get(SystemMetadataKey.REVERSE_GEOCODING_STATE);
|
||||||
|
return { lastUpdate: null, lastImportFileName: null, ...value };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -436,7 +436,7 @@ export class AV1Config extends BaseConfig {
|
|||||||
|
|
||||||
export class NVENCConfig extends BaseHWConfig {
|
export class NVENCConfig extends BaseHWConfig {
|
||||||
getSupportedCodecs() {
|
getSupportedCodecs() {
|
||||||
return [VideoCodec.H264, VideoCodec.HEVC];
|
return [VideoCodec.H264, VideoCodec.HEVC, VideoCodec.AV1];
|
||||||
}
|
}
|
||||||
|
|
||||||
getBaseInputOptions() {
|
getBaseInputOptions() {
|
||||||
@@ -566,7 +566,7 @@ export class QSVConfig extends BaseHWConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSupportedCodecs() {
|
getSupportedCodecs() {
|
||||||
return [VideoCodec.H264, VideoCodec.HEVC, VideoCodec.VP9];
|
return [VideoCodec.H264, VideoCodec.HEVC, VideoCodec.VP9, VideoCodec.AV1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// recommended from https://github.com/intel/media-delivery/blob/master/doc/benchmarks/intel-iris-xe-max-graphics/intel-iris-xe-max-graphics.md
|
// recommended from https://github.com/intel/media-delivery/blob/master/doc/benchmarks/intel-iris-xe-max-graphics/intel-iris-xe-max-graphics.md
|
||||||
|
|||||||
@@ -106,12 +106,6 @@ describe('mimeTypes', () => {
|
|||||||
expect(values).toEqual(values.map((mimeType) => mimeType.toLowerCase()));
|
expect(values).toEqual(values.map((mimeType) => mimeType.toLowerCase()));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be a sorted list', () => {
|
|
||||||
const keys = Object.keys(mimeTypes.profile);
|
|
||||||
// TODO: use toSorted in NodeJS 20.
|
|
||||||
expect(keys).toEqual([...keys].sort());
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const [extension, v] of Object.entries(mimeTypes.profile)) {
|
for (const [extension, v] of Object.entries(mimeTypes.profile)) {
|
||||||
it(`should lookup ${extension}`, () => {
|
it(`should lookup ${extension}`, () => {
|
||||||
expect(mimeTypes.lookup(`test.${extension}`)).toEqual(v[0]);
|
expect(mimeTypes.lookup(`test.${extension}`)).toEqual(v[0]);
|
||||||
@@ -128,12 +122,6 @@ describe('mimeTypes', () => {
|
|||||||
expect(values).toEqual(values.map((mimeType) => mimeType.toLowerCase()));
|
expect(values).toEqual(values.map((mimeType) => mimeType.toLowerCase()));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be a sorted list', () => {
|
|
||||||
const keys = Object.keys(mimeTypes.image);
|
|
||||||
// TODO: use toSorted in NodeJS 20.
|
|
||||||
expect(keys).toEqual([...keys].sort());
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should contain only image mime types', () => {
|
it('should contain only image mime types', () => {
|
||||||
const values = Object.values(mimeTypes.image).flat();
|
const values = Object.values(mimeTypes.image).flat();
|
||||||
expect(values).toEqual(values.filter((mimeType) => mimeType.startsWith('image/')));
|
expect(values).toEqual(values.filter((mimeType) => mimeType.startsWith('image/')));
|
||||||
@@ -157,7 +145,6 @@ describe('mimeTypes', () => {
|
|||||||
|
|
||||||
it('should be a sorted list', () => {
|
it('should be a sorted list', () => {
|
||||||
const keys = Object.keys(mimeTypes.video);
|
const keys = Object.keys(mimeTypes.video);
|
||||||
// TODO: use toSorted in NodeJS 20.
|
|
||||||
expect(keys).toEqual([...keys].sort());
|
expect(keys).toEqual([...keys].sort());
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -184,7 +171,6 @@ describe('mimeTypes', () => {
|
|||||||
|
|
||||||
it('should be a sorted list', () => {
|
it('should be a sorted list', () => {
|
||||||
const keys = Object.keys(mimeTypes.sidecar);
|
const keys = Object.keys(mimeTypes.sidecar);
|
||||||
// TODO: use toSorted in NodeJS 20.
|
|
||||||
expect(keys).toEqual([...keys].sort());
|
expect(keys).toEqual([...keys].sort());
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -198,4 +184,20 @@ describe('mimeTypes', () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('raw', () => {
|
||||||
|
it('should contain only lowercase mime types', () => {
|
||||||
|
const keys = Object.keys(mimeTypes.raw);
|
||||||
|
expect(keys).toEqual(keys.map((mimeType) => mimeType.toLowerCase()));
|
||||||
|
|
||||||
|
const values = Object.values(mimeTypes.raw).flat();
|
||||||
|
expect(values).toEqual(values.map((mimeType) => mimeType.toLowerCase()));
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const [extension, v] of Object.entries(mimeTypes.video)) {
|
||||||
|
it(`should lookup ${extension}`, () => {
|
||||||
|
expect(mimeTypes.lookup(`test.${extension}`)).toEqual(v[0]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import { extname } from 'node:path';
|
import { extname } from 'node:path';
|
||||||
import { AssetType } from 'src/entities/asset.entity';
|
import { AssetType } from 'src/entities/asset.entity';
|
||||||
|
|
||||||
const image: Record<string, string[]> = {
|
const raw: Record<string, string[]> = {
|
||||||
'.3fr': ['image/3fr', 'image/x-hasselblad-3fr'],
|
'.3fr': ['image/3fr', 'image/x-hasselblad-3fr'],
|
||||||
'.ari': ['image/ari', 'image/x-arriflex-ari'],
|
'.ari': ['image/ari', 'image/x-arriflex-ari'],
|
||||||
'.arw': ['image/arw', 'image/x-sony-arw'],
|
'.arw': ['image/arw', 'image/x-sony-arw'],
|
||||||
'.avif': ['image/avif'],
|
|
||||||
'.bmp': ['image/bmp'],
|
|
||||||
'.cap': ['image/cap', 'image/x-phaseone-cap'],
|
'.cap': ['image/cap', 'image/x-phaseone-cap'],
|
||||||
'.cin': ['image/cin', 'image/x-phantom-cin'],
|
'.cin': ['image/cin', 'image/x-phantom-cin'],
|
||||||
'.cr2': ['image/cr2', 'image/x-canon-cr2'],
|
'.cr2': ['image/cr2', 'image/x-canon-cr2'],
|
||||||
@@ -16,16 +14,7 @@ const image: Record<string, string[]> = {
|
|||||||
'.dng': ['image/dng', 'image/x-adobe-dng'],
|
'.dng': ['image/dng', 'image/x-adobe-dng'],
|
||||||
'.erf': ['image/erf', 'image/x-epson-erf'],
|
'.erf': ['image/erf', 'image/x-epson-erf'],
|
||||||
'.fff': ['image/fff', 'image/x-hasselblad-fff'],
|
'.fff': ['image/fff', 'image/x-hasselblad-fff'],
|
||||||
'.gif': ['image/gif'],
|
|
||||||
'.heic': ['image/heic'],
|
|
||||||
'.heif': ['image/heif'],
|
|
||||||
'.hif': ['image/hif'],
|
|
||||||
'.iiq': ['image/iiq', 'image/x-phaseone-iiq'],
|
'.iiq': ['image/iiq', 'image/x-phaseone-iiq'],
|
||||||
'.insp': ['image/jpeg'],
|
|
||||||
'.jpe': ['image/jpeg'],
|
|
||||||
'.jpeg': ['image/jpeg'],
|
|
||||||
'.jpg': ['image/jpeg'],
|
|
||||||
'.jxl': ['image/jxl'],
|
|
||||||
'.k25': ['image/k25', 'image/x-kodak-k25'],
|
'.k25': ['image/k25', 'image/x-kodak-k25'],
|
||||||
'.kdc': ['image/kdc', 'image/x-kodak-kdc'],
|
'.kdc': ['image/kdc', 'image/x-kodak-kdc'],
|
||||||
'.mrw': ['image/mrw', 'image/x-minolta-mrw'],
|
'.mrw': ['image/mrw', 'image/x-minolta-mrw'],
|
||||||
@@ -33,7 +22,6 @@ const image: Record<string, string[]> = {
|
|||||||
'.orf': ['image/orf', 'image/x-olympus-orf'],
|
'.orf': ['image/orf', 'image/x-olympus-orf'],
|
||||||
'.ori': ['image/ori', 'image/x-olympus-ori'],
|
'.ori': ['image/ori', 'image/x-olympus-ori'],
|
||||||
'.pef': ['image/pef', 'image/x-pentax-pef'],
|
'.pef': ['image/pef', 'image/x-pentax-pef'],
|
||||||
'.png': ['image/png'],
|
|
||||||
'.psd': ['image/psd', 'image/vnd.adobe.photoshop'],
|
'.psd': ['image/psd', 'image/vnd.adobe.photoshop'],
|
||||||
'.raf': ['image/raf', 'image/x-fuji-raf'],
|
'.raf': ['image/raf', 'image/x-fuji-raf'],
|
||||||
'.raw': ['image/raw', 'image/x-panasonic-raw'],
|
'.raw': ['image/raw', 'image/x-panasonic-raw'],
|
||||||
@@ -42,11 +30,27 @@ const image: Record<string, string[]> = {
|
|||||||
'.sr2': ['image/sr2', 'image/x-sony-sr2'],
|
'.sr2': ['image/sr2', 'image/x-sony-sr2'],
|
||||||
'.srf': ['image/srf', 'image/x-sony-srf'],
|
'.srf': ['image/srf', 'image/x-sony-srf'],
|
||||||
'.srw': ['image/srw', 'image/x-samsung-srw'],
|
'.srw': ['image/srw', 'image/x-samsung-srw'],
|
||||||
|
'.x3f': ['image/x3f', 'image/x-sigma-x3f'],
|
||||||
|
};
|
||||||
|
|
||||||
|
const image: Record<string, string[]> = {
|
||||||
|
...raw,
|
||||||
|
'.avif': ['image/avif'],
|
||||||
|
'.bmp': ['image/bmp'],
|
||||||
|
'.gif': ['image/gif'],
|
||||||
|
'.heic': ['image/heic'],
|
||||||
|
'.heif': ['image/heif'],
|
||||||
|
'.hif': ['image/hif'],
|
||||||
|
'.insp': ['image/jpeg'],
|
||||||
|
'.jpe': ['image/jpeg'],
|
||||||
|
'.jpeg': ['image/jpeg'],
|
||||||
|
'.jpg': ['image/jpeg'],
|
||||||
|
'.jxl': ['image/jxl'],
|
||||||
|
'.png': ['image/png'],
|
||||||
'.svg': ['image/svg'],
|
'.svg': ['image/svg'],
|
||||||
'.tif': ['image/tiff'],
|
'.tif': ['image/tiff'],
|
||||||
'.tiff': ['image/tiff'],
|
'.tiff': ['image/tiff'],
|
||||||
'.webp': ['image/webp'],
|
'.webp': ['image/webp'],
|
||||||
'.x3f': ['image/x3f', 'image/x-sigma-x3f'],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const profileExtensions = new Set(['.avif', '.dng', '.heic', '.heif', '.jpeg', '.jpg', '.png', '.webp', '.svg']);
|
const profileExtensions = new Set(['.avif', '.dng', '.heic', '.heif', '.jpeg', '.jpg', '.png', '.webp', '.svg']);
|
||||||
@@ -77,22 +81,25 @@ const sidecar: Record<string, string[]> = {
|
|||||||
'.xmp': ['application/xml', 'text/xml'],
|
'.xmp': ['application/xml', 'text/xml'],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const types = { ...image, ...video, ...sidecar };
|
||||||
|
|
||||||
const isType = (filename: string, r: Record<string, string[]>) => extname(filename).toLowerCase() in r;
|
const isType = (filename: string, r: Record<string, string[]>) => extname(filename).toLowerCase() in r;
|
||||||
|
|
||||||
const lookup = (filename: string) =>
|
const lookup = (filename: string) => types[extname(filename).toLowerCase()]?.[0] ?? 'application/octet-stream';
|
||||||
({ ...image, ...video, ...sidecar })[extname(filename).toLowerCase()]?.[0] ?? 'application/octet-stream';
|
|
||||||
|
|
||||||
export const mimeTypes = {
|
export const mimeTypes = {
|
||||||
image,
|
image,
|
||||||
profile,
|
profile,
|
||||||
sidecar,
|
sidecar,
|
||||||
video,
|
video,
|
||||||
|
raw,
|
||||||
|
|
||||||
isAsset: (filename: string) => isType(filename, image) || isType(filename, video),
|
isAsset: (filename: string) => isType(filename, image) || isType(filename, video),
|
||||||
isImage: (filename: string) => isType(filename, image),
|
isImage: (filename: string) => isType(filename, image),
|
||||||
isProfile: (filename: string) => isType(filename, profile),
|
isProfile: (filename: string) => isType(filename, profile),
|
||||||
isSidecar: (filename: string) => isType(filename, sidecar),
|
isSidecar: (filename: string) => isType(filename, sidecar),
|
||||||
isVideo: (filename: string) => isType(filename, video),
|
isVideo: (filename: string) => isType(filename, video),
|
||||||
|
isRaw: (filename: string) => isType(filename, raw),
|
||||||
lookup,
|
lookup,
|
||||||
assetType: (filename: string) => {
|
assetType: (filename: string) => {
|
||||||
const contentType = lookup(filename);
|
const contentType = lookup(filename);
|
||||||
|
|||||||
@@ -10,13 +10,8 @@ import { SchemaObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.inte
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { writeFileSync } from 'node:fs';
|
import { writeFileSync } from 'node:fs';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import {
|
import { CLIP_MODEL_INFO, serverVersion } from 'src/constants';
|
||||||
CLIP_MODEL_INFO,
|
import { ImmichCookie, ImmichHeader } from 'src/dtos/auth.dto';
|
||||||
IMMICH_ACCESS_COOKIE,
|
|
||||||
IMMICH_API_KEY_HEADER,
|
|
||||||
IMMICH_API_KEY_NAME,
|
|
||||||
serverVersion,
|
|
||||||
} from 'src/constants';
|
|
||||||
import { ILoggerRepository } from 'src/interfaces/logger.interface';
|
import { ILoggerRepository } from 'src/interfaces/logger.interface';
|
||||||
import { Metadata } from 'src/middleware/auth.guard';
|
import { Metadata } from 'src/middleware/auth.guard';
|
||||||
|
|
||||||
@@ -143,14 +138,14 @@ export const useSwagger = (app: INestApplication, isDevelopment: boolean) => {
|
|||||||
scheme: 'Bearer',
|
scheme: 'Bearer',
|
||||||
in: 'header',
|
in: 'header',
|
||||||
})
|
})
|
||||||
.addCookieAuth(IMMICH_ACCESS_COOKIE)
|
.addCookieAuth(ImmichCookie.ACCESS_TOKEN)
|
||||||
.addApiKey(
|
.addApiKey(
|
||||||
{
|
{
|
||||||
type: 'apiKey',
|
type: 'apiKey',
|
||||||
in: 'header',
|
in: 'header',
|
||||||
name: IMMICH_API_KEY_HEADER,
|
name: ImmichHeader.API_KEY,
|
||||||
},
|
},
|
||||||
IMMICH_API_KEY_NAME,
|
Metadata.API_KEY_SECURITY,
|
||||||
)
|
)
|
||||||
.addServer('/api')
|
.addServer('/api')
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { CookieOptions, Response } from 'express';
|
||||||
|
import { Duration } from 'luxon';
|
||||||
|
import { CookieResponse, ImmichCookie } from 'src/dtos/auth.dto';
|
||||||
|
|
||||||
|
export const respondWithCookie = <T>(res: Response, body: T, { isSecure, values }: CookieResponse) => {
|
||||||
|
const defaults: CookieOptions = {
|
||||||
|
path: '/',
|
||||||
|
sameSite: 'lax',
|
||||||
|
httpOnly: true,
|
||||||
|
secure: isSecure,
|
||||||
|
maxAge: Duration.fromObject({ days: 400 }).toMillis(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const cookieOptions: Record<ImmichCookie, CookieOptions> = {
|
||||||
|
[ImmichCookie.AUTH_TYPE]: defaults,
|
||||||
|
[ImmichCookie.ACCESS_TOKEN]: defaults,
|
||||||
|
// no httpOnly so that the client can know the auth state
|
||||||
|
[ImmichCookie.IS_AUTHENTICATED]: { ...defaults, httpOnly: false },
|
||||||
|
[ImmichCookie.SHARED_LINK_TOKEN]: { ...defaults, maxAge: Duration.fromObject({ days: 1 }).toMillis() },
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const { key, value } of values) {
|
||||||
|
const options = cookieOptions[key];
|
||||||
|
res.cookie(key, value, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return body;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const respondWithoutCookie = <T>(res: Response, body: T, cookies: ImmichCookie[]) => {
|
||||||
|
for (const cookie of cookies) {
|
||||||
|
res.clearCookie(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
return body;
|
||||||
|
};
|
||||||
Vendored
+41
@@ -759,4 +759,45 @@ export const assetStub = {
|
|||||||
fileSizeInByte: 5000,
|
fileSizeInByte: 5000,
|
||||||
} as ExifEntity,
|
} as ExifEntity,
|
||||||
}),
|
}),
|
||||||
|
imageDng: Object.freeze<AssetEntity>({
|
||||||
|
id: 'asset-id',
|
||||||
|
deviceAssetId: 'device-asset-id',
|
||||||
|
fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
|
||||||
|
fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
|
||||||
|
owner: userStub.user1,
|
||||||
|
ownerId: 'user-id',
|
||||||
|
deviceId: 'device-id',
|
||||||
|
originalPath: '/original/path.dng',
|
||||||
|
previewPath: '/uploads/user-id/thumbs/path.jpg',
|
||||||
|
checksum: Buffer.from('file hash', 'utf8'),
|
||||||
|
type: AssetType.IMAGE,
|
||||||
|
thumbnailPath: '/uploads/user-id/webp/path.ext',
|
||||||
|
thumbhash: Buffer.from('blablabla', 'base64'),
|
||||||
|
encodedVideoPath: null,
|
||||||
|
createdAt: new Date('2023-02-23T05:06:29.716Z'),
|
||||||
|
updatedAt: new Date('2023-02-23T05:06:29.716Z'),
|
||||||
|
localDateTime: new Date('2023-02-23T05:06:29.716Z'),
|
||||||
|
isFavorite: true,
|
||||||
|
isArchived: false,
|
||||||
|
isReadOnly: false,
|
||||||
|
duration: null,
|
||||||
|
isVisible: true,
|
||||||
|
isExternal: false,
|
||||||
|
livePhotoVideo: null,
|
||||||
|
livePhotoVideoId: null,
|
||||||
|
isOffline: false,
|
||||||
|
libraryId: 'library-id',
|
||||||
|
library: libraryStub.uploadLibrary1,
|
||||||
|
tags: [],
|
||||||
|
sharedLinks: [],
|
||||||
|
originalFileName: 'asset-id.jpg',
|
||||||
|
faces: [],
|
||||||
|
deletedAt: null,
|
||||||
|
sidecarPath: null,
|
||||||
|
exifInfo: {
|
||||||
|
fileSizeInByte: 5000,
|
||||||
|
profileDescription: 'Adobe RGB',
|
||||||
|
bitsPerSample: 14,
|
||||||
|
} as ExifEntity,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
|||||||
Vendored
+14
-44
@@ -129,51 +129,21 @@ export const loginResponseStub = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
user1oauth: {
|
user1oauth: {
|
||||||
response: {
|
accessToken: 'cmFuZG9tLWJ5dGVz',
|
||||||
accessToken: 'cmFuZG9tLWJ5dGVz',
|
userId: 'user-id',
|
||||||
userId: 'user-id',
|
userEmail: 'immich@test.com',
|
||||||
userEmail: 'immich@test.com',
|
name: 'immich_name',
|
||||||
name: 'immich_name',
|
profileImagePath: '',
|
||||||
profileImagePath: '',
|
isAdmin: false,
|
||||||
isAdmin: false,
|
shouldChangePassword: false,
|
||||||
shouldChangePassword: false,
|
|
||||||
},
|
|
||||||
cookie: [
|
|
||||||
'immich_access_token=cmFuZG9tLWJ5dGVz; HttpOnly; Secure; Path=/; Max-Age=34560000; SameSite=Lax;',
|
|
||||||
'immich_auth_type=oauth; HttpOnly; Secure; Path=/; Max-Age=34560000; SameSite=Lax;',
|
|
||||||
'immich_is_authenticated=true; Secure; Path=/; Max-Age=34560000; SameSite=Lax;',
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
user1password: {
|
user1password: {
|
||||||
response: {
|
accessToken: 'cmFuZG9tLWJ5dGVz',
|
||||||
accessToken: 'cmFuZG9tLWJ5dGVz',
|
userId: 'user-id',
|
||||||
userId: 'user-id',
|
userEmail: 'immich@test.com',
|
||||||
userEmail: 'immich@test.com',
|
name: 'immich_name',
|
||||||
name: 'immich_name',
|
profileImagePath: '',
|
||||||
profileImagePath: '',
|
isAdmin: false,
|
||||||
isAdmin: false,
|
shouldChangePassword: false,
|
||||||
shouldChangePassword: false,
|
|
||||||
},
|
|
||||||
cookie: [
|
|
||||||
'immich_access_token=cmFuZG9tLWJ5dGVz; HttpOnly; Secure; Path=/; Max-Age=34560000; SameSite=Lax;',
|
|
||||||
'immich_auth_type=password; HttpOnly; Secure; Path=/; Max-Age=34560000; SameSite=Lax;',
|
|
||||||
'immich_is_authenticated=true; Secure; Path=/; Max-Age=34560000; SameSite=Lax;',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
user1insecure: {
|
|
||||||
response: {
|
|
||||||
accessToken: 'cmFuZG9tLWJ5dGVz',
|
|
||||||
userId: 'user-id',
|
|
||||||
userEmail: 'immich@test.com',
|
|
||||||
name: 'immich_name',
|
|
||||||
profileImagePath: '',
|
|
||||||
isAdmin: false,
|
|
||||||
shouldChangePassword: false,
|
|
||||||
},
|
|
||||||
cookie: [
|
|
||||||
'immich_access_token=cmFuZG9tLWJ5dGVz; HttpOnly; Path=/; Max-Age=34560000; SameSite=Lax;',
|
|
||||||
'immich_auth_type=password; HttpOnly; Path=/; Max-Age=34560000; SameSite=Lax;',
|
|
||||||
'immich_is_authenticated=true; Path=/; Max-Age=34560000; SameSite=Lax;',
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ import { Mocked, vitest } from 'vitest';
|
|||||||
export const newMediaRepositoryMock = (): Mocked<IMediaRepository> => {
|
export const newMediaRepositoryMock = (): Mocked<IMediaRepository> => {
|
||||||
return {
|
return {
|
||||||
generateThumbhash: vitest.fn(),
|
generateThumbhash: vitest.fn(),
|
||||||
|
extract: vitest.fn().mockResolvedValue(false),
|
||||||
resize: vitest.fn(),
|
resize: vitest.fn(),
|
||||||
crop: vitest.fn(),
|
crop: vitest.fn(),
|
||||||
probe: vitest.fn(),
|
probe: vitest.fn(),
|
||||||
transcode: vitest.fn(),
|
transcode: vitest.fn(),
|
||||||
|
getImageDimensions: vitest.fn(),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import { Mocked, vitest } from 'vitest';
|
|||||||
|
|
||||||
export const newSessionRepositoryMock = (): Mocked<ISessionRepository> => {
|
export const newSessionRepositoryMock = (): Mocked<ISessionRepository> => {
|
||||||
return {
|
return {
|
||||||
create: vitest.fn(),
|
create: vitest.fn() as any,
|
||||||
update: vitest.fn(),
|
update: vitest.fn() as any,
|
||||||
delete: vitest.fn(),
|
delete: vitest.fn(),
|
||||||
getByToken: vitest.fn(),
|
getByToken: vitest.fn(),
|
||||||
getByUserId: vitest.fn(),
|
getByUserId: vitest.fn(),
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user