forked from Cutlery/immich
		
	fix(server): require local admin account (#1070)
This commit is contained in:
		
							parent
							
								
									3bb103c6b6
								
							
						
					
					
						commit
						14889e7d85
					
				
							
								
								
									
										10
									
								
								mobile/openapi/doc/UserApi.md
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										10
									
								
								mobile/openapi/doc/UserApi.md
									
									
									
										generated
									
									
									
								
							@ -335,7 +335,7 @@ 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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# **getUserCount**
 | 
					# **getUserCount**
 | 
				
			||||||
> UserCountResponseDto getUserCount()
 | 
					> UserCountResponseDto getUserCount(admin)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -344,9 +344,10 @@ No authorization required
 | 
				
			|||||||
import 'package:openapi/api.dart';
 | 
					import 'package:openapi/api.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
final api_instance = UserApi();
 | 
					final api_instance = UserApi();
 | 
				
			||||||
 | 
					final admin = true; // bool | 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
try {
 | 
					try {
 | 
				
			||||||
    final result = api_instance.getUserCount();
 | 
					    final result = api_instance.getUserCount(admin);
 | 
				
			||||||
    print(result);
 | 
					    print(result);
 | 
				
			||||||
} catch (e) {
 | 
					} catch (e) {
 | 
				
			||||||
    print('Exception when calling UserApi->getUserCount: $e\n');
 | 
					    print('Exception when calling UserApi->getUserCount: $e\n');
 | 
				
			||||||
@ -354,7 +355,10 @@ try {
 | 
				
			|||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Parameters
 | 
					### Parameters
 | 
				
			||||||
This endpoint does not need any parameter.
 | 
					
 | 
				
			||||||
 | 
					Name | Type | Description  | Notes
 | 
				
			||||||
 | 
					------------- | ------------- | ------------- | -------------
 | 
				
			||||||
 | 
					 **admin** | **bool**|  | [optional] [default to false]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Return type
 | 
					### Return type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										16
									
								
								mobile/openapi/lib/api/user_api.dart
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										16
									
								
								mobile/openapi/lib/api/user_api.dart
									
									
									
										generated
									
									
									
								
							@ -358,7 +358,10 @@ class UserApi {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Performs an HTTP 'GET /user/count' operation and returns the [Response].
 | 
					  /// Performs an HTTP 'GET /user/count' operation and returns the [Response].
 | 
				
			||||||
  Future<Response> getUserCountWithHttpInfo() async {
 | 
					  /// Parameters:
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  /// * [bool] admin:
 | 
				
			||||||
 | 
					  Future<Response> getUserCountWithHttpInfo({ bool? admin, }) async {
 | 
				
			||||||
    // ignore: prefer_const_declarations
 | 
					    // ignore: prefer_const_declarations
 | 
				
			||||||
    final path = r'/user/count';
 | 
					    final path = r'/user/count';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -369,6 +372,10 @@ class UserApi {
 | 
				
			|||||||
    final headerParams = <String, String>{};
 | 
					    final headerParams = <String, String>{};
 | 
				
			||||||
    final formParams = <String, String>{};
 | 
					    final formParams = <String, String>{};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (admin != null) {
 | 
				
			||||||
 | 
					      queryParams.addAll(_queryParams('', 'admin', admin));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const contentTypes = <String>[];
 | 
					    const contentTypes = <String>[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -383,8 +390,11 @@ class UserApi {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<UserCountResponseDto?> getUserCount() async {
 | 
					  /// Parameters:
 | 
				
			||||||
    final response = await getUserCountWithHttpInfo();
 | 
					  ///
 | 
				
			||||||
 | 
					  /// * [bool] admin:
 | 
				
			||||||
 | 
					  Future<UserCountResponseDto?> getUserCount({ bool? admin, }) async {
 | 
				
			||||||
 | 
					    final response = await getUserCountWithHttpInfo( admin: admin, );
 | 
				
			||||||
    if (response.statusCode >= HttpStatus.badRequest) {
 | 
					    if (response.statusCode >= HttpStatus.badRequest) {
 | 
				
			||||||
      throw ApiException(response.statusCode, await _decodeBodyBytes(response));
 | 
					      throw ApiException(response.statusCode, await _decodeBodyBytes(response));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								mobile/openapi/test/user_api_test.dart
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								mobile/openapi/test/user_api_test.dart
									
									
									
										generated
									
									
									
								
							@ -52,7 +52,7 @@ void main() {
 | 
				
			|||||||
      // TODO
 | 
					      // TODO
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //Future<UserCountResponseDto> getUserCount() async
 | 
					    //Future<UserCountResponseDto> getUserCount({ bool admin }) async
 | 
				
			||||||
    test('test getUserCount', () async {
 | 
					    test('test getUserCount', () async {
 | 
				
			||||||
      // TODO
 | 
					      // TODO
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										12
									
								
								server/apps/immich/src/api-v1/user/dto/user-count.dto.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								server/apps/immich/src/api-v1/user/dto/user-count.dto.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					import { Transform } from 'class-transformer';
 | 
				
			||||||
 | 
					import { IsBoolean, IsOptional } from 'class-validator';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class UserCountDto {
 | 
				
			||||||
 | 
					  @IsBoolean()
 | 
				
			||||||
 | 
					  @IsOptional()
 | 
				
			||||||
 | 
					  @Transform(({ value }) => value === 'true')
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * When true, return the number of admins accounts
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  admin?: boolean = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										30
									
								
								server/apps/immich/src/api-v1/user/user-repository.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								server/apps/immich/src/api-v1/user/user-repository.spec.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					import { UserEntity } from '@app/database/entities/user.entity';
 | 
				
			||||||
 | 
					import { BadRequestException } from '@nestjs/common';
 | 
				
			||||||
 | 
					import { Repository } from 'typeorm';
 | 
				
			||||||
 | 
					import { UserRepository } from './user-repository';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('UserRepository', () => {
 | 
				
			||||||
 | 
					  let sui: UserRepository;
 | 
				
			||||||
 | 
					  let userRepositoryMock: jest.Mocked<Repository<UserEntity>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  beforeAll(() => {
 | 
				
			||||||
 | 
					    userRepositoryMock = {
 | 
				
			||||||
 | 
					      findOne: jest.fn(),
 | 
				
			||||||
 | 
					      save: jest.fn(),
 | 
				
			||||||
 | 
					    } as unknown as jest.Mocked<Repository<UserEntity>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sui = new UserRepository(userRepositoryMock);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('should be defined', () => {
 | 
				
			||||||
 | 
					    expect(sui).toBeDefined();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe('create', () => {
 | 
				
			||||||
 | 
					    it('should not create a user if there is no local admin account', async () => {
 | 
				
			||||||
 | 
					      userRepositoryMock.findOne.mockResolvedValue(null);
 | 
				
			||||||
 | 
					      await expect(sui.create({ isAdmin: false })).rejects.toBeInstanceOf(BadRequestException);
 | 
				
			||||||
 | 
					      expect(userRepositoryMock.findOne).toHaveBeenCalled();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@ -60,6 +60,11 @@ export class UserRepository implements IUserRepository {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public async create(user: Partial<UserEntity>): Promise<UserEntity> {
 | 
					  public async create(user: Partial<UserEntity>): Promise<UserEntity> {
 | 
				
			||||||
 | 
					    const localAdmin = await this.getAdmin();
 | 
				
			||||||
 | 
					    if (!localAdmin && !user.isAdmin) {
 | 
				
			||||||
 | 
					      throw new BadRequestException('The first registered account must the administrator.');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (user.password) {
 | 
					    if (user.password) {
 | 
				
			||||||
      user.salt = await bcrypt.genSalt();
 | 
					      user.salt = await bcrypt.genSalt();
 | 
				
			||||||
      user.password = await this.hashPassword(user.password, user.salt);
 | 
					      user.password = await this.hashPassword(user.password, user.salt);
 | 
				
			||||||
 | 
				
			|||||||
@ -26,6 +26,7 @@ import { UserResponseDto } from './response-dto/user-response.dto';
 | 
				
			|||||||
import { UserCountResponseDto } from './response-dto/user-count-response.dto';
 | 
					import { UserCountResponseDto } from './response-dto/user-count-response.dto';
 | 
				
			||||||
import { CreateProfileImageDto } from './dto/create-profile-image.dto';
 | 
					import { CreateProfileImageDto } from './dto/create-profile-image.dto';
 | 
				
			||||||
import { CreateProfileImageResponseDto } from './response-dto/create-profile-image-response.dto';
 | 
					import { CreateProfileImageResponseDto } from './response-dto/create-profile-image-response.dto';
 | 
				
			||||||
 | 
					import { UserCountDto } from './dto/user-count.dto';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ApiTags('User')
 | 
					@ApiTags('User')
 | 
				
			||||||
@Controller('user')
 | 
					@Controller('user')
 | 
				
			||||||
@ -64,8 +65,8 @@ export class UserController {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @Get('/count')
 | 
					  @Get('/count')
 | 
				
			||||||
  async getUserCount(): Promise<UserCountResponseDto> {
 | 
					  async getUserCount(@Query(new ValidationPipe({ transform: true })) dto: UserCountDto): Promise<UserCountResponseDto> {
 | 
				
			||||||
    return await this.userService.getUserCount();
 | 
					    return await this.userService.getUserCount(dto);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @Authenticated({ admin: true })
 | 
					  @Authenticated({ admin: true })
 | 
				
			||||||
 | 
				
			|||||||
@ -14,6 +14,7 @@ import { createReadStream } from 'fs';
 | 
				
			|||||||
import { AuthUserDto } from '../../decorators/auth-user.decorator';
 | 
					import { AuthUserDto } from '../../decorators/auth-user.decorator';
 | 
				
			||||||
import { CreateUserDto } from './dto/create-user.dto';
 | 
					import { CreateUserDto } from './dto/create-user.dto';
 | 
				
			||||||
import { UpdateUserDto } from './dto/update-user.dto';
 | 
					import { UpdateUserDto } from './dto/update-user.dto';
 | 
				
			||||||
 | 
					import { UserCountDto } from './dto/user-count.dto';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  CreateProfileImageResponseDto,
 | 
					  CreateProfileImageResponseDto,
 | 
				
			||||||
  mapCreateProfileImageResponse,
 | 
					  mapCreateProfileImageResponse,
 | 
				
			||||||
@ -57,8 +58,12 @@ export class UserService {
 | 
				
			|||||||
    return mapUser(user);
 | 
					    return mapUser(user);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async getUserCount(): Promise<UserCountResponseDto> {
 | 
					  async getUserCount(dto: UserCountDto): Promise<UserCountResponseDto> {
 | 
				
			||||||
    const users = await this.userRepository.getList();
 | 
					    let users = await this.userRepository.getList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (dto.admin) {
 | 
				
			||||||
 | 
					      users = users.filter((user) => user.isAdmin);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return mapUserCountResponse(users.length);
 | 
					    return mapUserCountResponse(users.length);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -166,7 +166,17 @@
 | 
				
			|||||||
    "/user/count": {
 | 
					    "/user/count": {
 | 
				
			||||||
      "get": {
 | 
					      "get": {
 | 
				
			||||||
        "operationId": "getUserCount",
 | 
					        "operationId": "getUserCount",
 | 
				
			||||||
        "parameters": [],
 | 
					        "parameters": [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            "name": "admin",
 | 
				
			||||||
 | 
					            "required": false,
 | 
				
			||||||
 | 
					            "in": "query",
 | 
				
			||||||
 | 
					            "schema": {
 | 
				
			||||||
 | 
					              "default": false,
 | 
				
			||||||
 | 
					              "type": "boolean"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
        "responses": {
 | 
					        "responses": {
 | 
				
			||||||
          "200": {
 | 
					          "200": {
 | 
				
			||||||
            "description": "",
 | 
					            "description": "",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										22
									
								
								web/src/api/open-api/api.ts
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										22
									
								
								web/src/api/open-api/api.ts
									
									
									
										generated
									
									
									
								
							@ -6108,10 +6108,11 @@ export const UserApiAxiosParamCreator = function (configuration?: Configuration)
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * 
 | 
					         * 
 | 
				
			||||||
 | 
					         * @param {boolean} [admin] 
 | 
				
			||||||
         * @param {*} [options] Override http request option.
 | 
					         * @param {*} [options] Override http request option.
 | 
				
			||||||
         * @throws {RequiredError}
 | 
					         * @throws {RequiredError}
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        getUserCount: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
 | 
					        getUserCount: async (admin?: boolean, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
 | 
				
			||||||
            const localVarPath = `/user/count`;
 | 
					            const localVarPath = `/user/count`;
 | 
				
			||||||
            // use dummy base URL string because the URL constructor only accepts absolute URLs.
 | 
					            // use dummy base URL string because the URL constructor only accepts absolute URLs.
 | 
				
			||||||
            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
 | 
					            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
 | 
				
			||||||
@ -6124,6 +6125,10 @@ export const UserApiAxiosParamCreator = function (configuration?: Configuration)
 | 
				
			|||||||
            const localVarHeaderParameter = {} as any;
 | 
					            const localVarHeaderParameter = {} as any;
 | 
				
			||||||
            const localVarQueryParameter = {} as any;
 | 
					            const localVarQueryParameter = {} as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (admin !== undefined) {
 | 
				
			||||||
 | 
					                localVarQueryParameter['admin'] = admin;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
            setSearchParams(localVarUrlObj, localVarQueryParameter);
 | 
					            setSearchParams(localVarUrlObj, localVarQueryParameter);
 | 
				
			||||||
@ -6292,11 +6297,12 @@ export const UserApiFp = function(configuration?: Configuration) {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * 
 | 
					         * 
 | 
				
			||||||
 | 
					         * @param {boolean} [admin] 
 | 
				
			||||||
         * @param {*} [options] Override http request option.
 | 
					         * @param {*} [options] Override http request option.
 | 
				
			||||||
         * @throws {RequiredError}
 | 
					         * @throws {RequiredError}
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        async getUserCount(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<UserCountResponseDto>> {
 | 
					        async getUserCount(admin?: boolean, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<UserCountResponseDto>> {
 | 
				
			||||||
            const localVarAxiosArgs = await localVarAxiosParamCreator.getUserCount(options);
 | 
					            const localVarAxiosArgs = await localVarAxiosParamCreator.getUserCount(admin, options);
 | 
				
			||||||
            return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
 | 
					            return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
@ -6393,11 +6399,12 @@ export const UserApiFactory = function (configuration?: Configuration, basePath?
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * 
 | 
					         * 
 | 
				
			||||||
 | 
					         * @param {boolean} [admin] 
 | 
				
			||||||
         * @param {*} [options] Override http request option.
 | 
					         * @param {*} [options] Override http request option.
 | 
				
			||||||
         * @throws {RequiredError}
 | 
					         * @throws {RequiredError}
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        getUserCount(options?: any): AxiosPromise<UserCountResponseDto> {
 | 
					        getUserCount(admin?: boolean, options?: any): AxiosPromise<UserCountResponseDto> {
 | 
				
			||||||
            return localVarFp.getUserCount(options).then((request) => request(axios, basePath));
 | 
					            return localVarFp.getUserCount(admin, options).then((request) => request(axios, basePath));
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * 
 | 
					         * 
 | 
				
			||||||
@ -6505,12 +6512,13 @@ export class UserApi extends BaseAPI {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 
 | 
					     * 
 | 
				
			||||||
 | 
					     * @param {boolean} [admin] 
 | 
				
			||||||
     * @param {*} [options] Override http request option.
 | 
					     * @param {*} [options] Override http request option.
 | 
				
			||||||
     * @throws {RequiredError}
 | 
					     * @throws {RequiredError}
 | 
				
			||||||
     * @memberof UserApi
 | 
					     * @memberof UserApi
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public getUserCount(options?: AxiosRequestConfig) {
 | 
					    public getUserCount(admin?: boolean, options?: AxiosRequestConfig) {
 | 
				
			||||||
        return UserApiFp(this.configuration).getUserCount(options).then((request) => request(this.axios, this.basePath));
 | 
					        return UserApiFp(this.configuration).getUserCount(admin, options).then((request) => request(this.axios, this.basePath));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,5 @@
 | 
				
			|||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
	import { goto } from '$app/navigation';
 | 
						import { goto } from '$app/navigation';
 | 
				
			||||||
	import type { PageData } from './$types';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	export let data: PageData;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	async function onGettingStartedClicked() {
 | 
					 | 
				
			||||||
		data.isAdminUserExist ? await goto('/auth/login') : await goto('/auth/register');
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<svelte:head>
 | 
					<svelte:head>
 | 
				
			||||||
@ -26,7 +19,7 @@
 | 
				
			|||||||
		</h1>
 | 
							</h1>
 | 
				
			||||||
		<button
 | 
							<button
 | 
				
			||||||
			class="border px-4 py-4 rounded-md bg-immich-primary dark:bg-immich-dark-primary dark:text-immich-dark-gray dark:border-immich-dark-gray hover:bg-immich-primary/75 text-white font-bold w-[200px]"
 | 
								class="border px-4 py-4 rounded-md bg-immich-primary dark:bg-immich-dark-primary dark:text-immich-dark-gray dark:border-immich-dark-gray hover:bg-immich-primary/75 text-white font-bold w-[200px]"
 | 
				
			||||||
			on:click={onGettingStartedClicked}
 | 
								on:click={() => goto('/auth/login')}
 | 
				
			||||||
			>Getting Started
 | 
								>Getting Started
 | 
				
			||||||
		</button>
 | 
							</button>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,20 +1,10 @@
 | 
				
			|||||||
export const prerender = false;
 | 
					export const prerender = false;
 | 
				
			||||||
import { redirect } from '@sveltejs/kit';
 | 
					import { redirect } from '@sveltejs/kit';
 | 
				
			||||||
import { api } from '@api';
 | 
					 | 
				
			||||||
import type { PageLoad } from './$types';
 | 
					import type { PageLoad } from './$types';
 | 
				
			||||||
import { browser } from '$app/environment';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const load: PageLoad = async ({ parent }) => {
 | 
					export const load: PageLoad = async ({ parent }) => {
 | 
				
			||||||
	const { user } = await parent();
 | 
						const { user } = await parent();
 | 
				
			||||||
	if (user) {
 | 
						if (user) {
 | 
				
			||||||
		throw redirect(302, '/photos');
 | 
							throw redirect(302, '/photos');
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (browser) {
 | 
					 | 
				
			||||||
		const { data } = await api.userApi.getUserCount();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return {
 | 
					 | 
				
			||||||
			isAdminUserExist: data.userCount != 0
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										13
									
								
								web/src/routes/auth/login/+page.server.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								web/src/routes/auth/login/+page.server.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					import { redirect } from '@sveltejs/kit';
 | 
				
			||||||
 | 
					import type { PageServerLoad } from './$types';
 | 
				
			||||||
 | 
					import { serverApi } from '@api';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const load: PageServerLoad = async () => {
 | 
				
			||||||
 | 
						const { data } = await serverApi.userApi.getUserCount(true);
 | 
				
			||||||
 | 
						if (data.userCount === 0) {
 | 
				
			||||||
 | 
							// Admin not registered
 | 
				
			||||||
 | 
							throw redirect(302, '/auth/register');
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -3,7 +3,7 @@ import type { PageServerLoad } from './$types';
 | 
				
			|||||||
import { serverApi } from '@api';
 | 
					import { serverApi } from '@api';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const load: PageServerLoad = async () => {
 | 
					export const load: PageServerLoad = async () => {
 | 
				
			||||||
	const { data } = await serverApi.userApi.getUserCount();
 | 
						const { data } = await serverApi.userApi.getUserCount(true);
 | 
				
			||||||
	if (data.userCount != 0) {
 | 
						if (data.userCount != 0) {
 | 
				
			||||||
		// Admin has been registered, redirect to login
 | 
							// Admin has been registered, redirect to login
 | 
				
			||||||
		throw redirect(302, '/auth/login');
 | 
							throw redirect(302, '/auth/login');
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user