forked from Cutlery/immich
refactor(server): auth dtos (#4881)
* refactor: auth dtos * chore: open api
This commit is contained in:
parent
5c602bf4d4
commit
5423f1c25b
41
cli/src/api/open-api/api.ts
generated
41
cli/src/api/open-api/api.ts
generated
@ -209,43 +209,6 @@ export interface AddUsersDto {
|
|||||||
*/
|
*/
|
||||||
'sharedUserIds': Array<string>;
|
'sharedUserIds': Array<string>;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface AdminSignupResponseDto
|
|
||||||
*/
|
|
||||||
export interface AdminSignupResponseDto {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof AdminSignupResponseDto
|
|
||||||
*/
|
|
||||||
'createdAt': string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof AdminSignupResponseDto
|
|
||||||
*/
|
|
||||||
'email': string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof AdminSignupResponseDto
|
|
||||||
*/
|
|
||||||
'firstName': string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof AdminSignupResponseDto
|
|
||||||
*/
|
|
||||||
'id': string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof AdminSignupResponseDto
|
|
||||||
*/
|
|
||||||
'lastName': string;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
@ -10509,7 +10472,7 @@ export const AuthenticationApiFp = function(configuration?: Configuration) {
|
|||||||
* @param {*} [options] Override http request option.
|
* @param {*} [options] Override http request option.
|
||||||
* @throws {RequiredError}
|
* @throws {RequiredError}
|
||||||
*/
|
*/
|
||||||
async signUpAdmin(signUpDto: SignUpDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AdminSignupResponseDto>> {
|
async signUpAdmin(signUpDto: SignUpDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<UserResponseDto>> {
|
||||||
const localVarAxiosArgs = await localVarAxiosParamCreator.signUpAdmin(signUpDto, options);
|
const localVarAxiosArgs = await localVarAxiosParamCreator.signUpAdmin(signUpDto, options);
|
||||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||||
},
|
},
|
||||||
@ -10589,7 +10552,7 @@ export const AuthenticationApiFactory = function (configuration?: Configuration,
|
|||||||
* @param {*} [options] Override http request option.
|
* @param {*} [options] Override http request option.
|
||||||
* @throws {RequiredError}
|
* @throws {RequiredError}
|
||||||
*/
|
*/
|
||||||
signUpAdmin(requestParameters: AuthenticationApiSignUpAdminRequest, options?: AxiosRequestConfig): AxiosPromise<AdminSignupResponseDto> {
|
signUpAdmin(requestParameters: AuthenticationApiSignUpAdminRequest, options?: AxiosRequestConfig): AxiosPromise<UserResponseDto> {
|
||||||
return localVarFp.signUpAdmin(requestParameters.signUpDto, options).then((request) => request(axios, basePath));
|
return localVarFp.signUpAdmin(requestParameters.signUpDto, options).then((request) => request(axios, basePath));
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
3
mobile/openapi/.openapi-generator/FILES
generated
3
mobile/openapi/.openapi-generator/FILES
generated
@ -13,7 +13,6 @@ doc/ActivityCreateDto.md
|
|||||||
doc/ActivityResponseDto.md
|
doc/ActivityResponseDto.md
|
||||||
doc/ActivityStatisticsResponseDto.md
|
doc/ActivityStatisticsResponseDto.md
|
||||||
doc/AddUsersDto.md
|
doc/AddUsersDto.md
|
||||||
doc/AdminSignupResponseDto.md
|
|
||||||
doc/AlbumApi.md
|
doc/AlbumApi.md
|
||||||
doc/AlbumCountResponseDto.md
|
doc/AlbumCountResponseDto.md
|
||||||
doc/AlbumResponseDto.md
|
doc/AlbumResponseDto.md
|
||||||
@ -198,7 +197,6 @@ 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_signup_response_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/all_job_status_response_dto.dart
|
lib/model/all_job_status_response_dto.dart
|
||||||
@ -347,7 +345,6 @@ 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_signup_response_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
|
||||||
|
1
mobile/openapi/README.md
generated
1
mobile/openapi/README.md
generated
@ -212,7 +212,6 @@ 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)
|
||||||
- [AdminSignupResponseDto](doc//AdminSignupResponseDto.md)
|
|
||||||
- [AlbumCountResponseDto](doc//AlbumCountResponseDto.md)
|
- [AlbumCountResponseDto](doc//AlbumCountResponseDto.md)
|
||||||
- [AlbumResponseDto](doc//AlbumResponseDto.md)
|
- [AlbumResponseDto](doc//AlbumResponseDto.md)
|
||||||
- [AllJobStatusResponseDto](doc//AllJobStatusResponseDto.md)
|
- [AllJobStatusResponseDto](doc//AllJobStatusResponseDto.md)
|
||||||
|
19
mobile/openapi/doc/AdminSignupResponseDto.md
generated
19
mobile/openapi/doc/AdminSignupResponseDto.md
generated
@ -1,19 +0,0 @@
|
|||||||
# openapi.model.AdminSignupResponseDto
|
|
||||||
|
|
||||||
## Load the model package
|
|
||||||
```dart
|
|
||||||
import 'package:openapi/api.dart';
|
|
||||||
```
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**createdAt** | [**DateTime**](DateTime.md) | |
|
|
||||||
**email** | **String** | |
|
|
||||||
**firstName** | **String** | |
|
|
||||||
**id** | **String** | |
|
|
||||||
**lastName** | **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)
|
|
||||||
|
|
||||||
|
|
4
mobile/openapi/doc/AuthenticationApi.md
generated
4
mobile/openapi/doc/AuthenticationApi.md
generated
@ -322,7 +322,7 @@ void (empty response body)
|
|||||||
[[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)
|
||||||
|
|
||||||
# **signUpAdmin**
|
# **signUpAdmin**
|
||||||
> AdminSignupResponseDto signUpAdmin(signUpDto)
|
> UserResponseDto signUpAdmin(signUpDto)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -349,7 +349,7 @@ Name | Type | Description | Notes
|
|||||||
|
|
||||||
### Return type
|
### Return type
|
||||||
|
|
||||||
[**AdminSignupResponseDto**](AdminSignupResponseDto.md)
|
[**UserResponseDto**](UserResponseDto.md)
|
||||||
|
|
||||||
### Authorization
|
### Authorization
|
||||||
|
|
||||||
|
16
mobile/openapi/doc/LoginResponseDto.md
generated
16
mobile/openapi/doc/LoginResponseDto.md
generated
@ -8,14 +8,14 @@ import 'package:openapi/api.dart';
|
|||||||
## Properties
|
## Properties
|
||||||
Name | Type | Description | Notes
|
Name | Type | Description | Notes
|
||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**accessToken** | **String** | | [readonly]
|
**accessToken** | **String** | |
|
||||||
**firstName** | **String** | | [readonly]
|
**firstName** | **String** | |
|
||||||
**isAdmin** | **bool** | | [readonly]
|
**isAdmin** | **bool** | |
|
||||||
**lastName** | **String** | | [readonly]
|
**lastName** | **String** | |
|
||||||
**profileImagePath** | **String** | | [readonly]
|
**profileImagePath** | **String** | |
|
||||||
**shouldChangePassword** | **bool** | | [readonly]
|
**shouldChangePassword** | **bool** | |
|
||||||
**userEmail** | **String** | | [readonly]
|
**userEmail** | **String** | |
|
||||||
**userId** | **String** | | [readonly]
|
**userId** | **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)
|
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
1
mobile/openapi/lib/api.dart
generated
1
mobile/openapi/lib/api.dart
generated
@ -54,7 +54,6 @@ 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_signup_response_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/all_job_status_response_dto.dart';
|
part 'model/all_job_status_response_dto.dart';
|
||||||
|
4
mobile/openapi/lib/api/authentication_api.dart
generated
4
mobile/openapi/lib/api/authentication_api.dart
generated
@ -300,7 +300,7 @@ class AuthenticationApi {
|
|||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
/// * [SignUpDto] signUpDto (required):
|
/// * [SignUpDto] signUpDto (required):
|
||||||
Future<AdminSignupResponseDto?> signUpAdmin(SignUpDto signUpDto,) async {
|
Future<UserResponseDto?> signUpAdmin(SignUpDto signUpDto,) async {
|
||||||
final response = await signUpAdminWithHttpInfo(signUpDto,);
|
final response = await signUpAdminWithHttpInfo(signUpDto,);
|
||||||
if (response.statusCode >= HttpStatus.badRequest) {
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
@ -309,7 +309,7 @@ class AuthenticationApi {
|
|||||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||||
// FormatException when trying to decode an empty string.
|
// FormatException when trying to decode an empty string.
|
||||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AdminSignupResponseDto',) as AdminSignupResponseDto;
|
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserResponseDto',) as UserResponseDto;
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
2
mobile/openapi/lib/api_client.dart
generated
2
mobile/openapi/lib/api_client.dart
generated
@ -197,8 +197,6 @@ class ApiClient {
|
|||||||
return ActivityStatisticsResponseDto.fromJson(value);
|
return ActivityStatisticsResponseDto.fromJson(value);
|
||||||
case 'AddUsersDto':
|
case 'AddUsersDto':
|
||||||
return AddUsersDto.fromJson(value);
|
return AddUsersDto.fromJson(value);
|
||||||
case 'AdminSignupResponseDto':
|
|
||||||
return AdminSignupResponseDto.fromJson(value);
|
|
||||||
case 'AlbumCountResponseDto':
|
case 'AlbumCountResponseDto':
|
||||||
return AlbumCountResponseDto.fromJson(value);
|
return AlbumCountResponseDto.fromJson(value);
|
||||||
case 'AlbumResponseDto':
|
case 'AlbumResponseDto':
|
||||||
|
130
mobile/openapi/lib/model/admin_signup_response_dto.dart
generated
130
mobile/openapi/lib/model/admin_signup_response_dto.dart
generated
@ -1,130 +0,0 @@
|
|||||||
//
|
|
||||||
// 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 AdminSignupResponseDto {
|
|
||||||
/// Returns a new [AdminSignupResponseDto] instance.
|
|
||||||
AdminSignupResponseDto({
|
|
||||||
required this.createdAt,
|
|
||||||
required this.email,
|
|
||||||
required this.firstName,
|
|
||||||
required this.id,
|
|
||||||
required this.lastName,
|
|
||||||
});
|
|
||||||
|
|
||||||
DateTime createdAt;
|
|
||||||
|
|
||||||
String email;
|
|
||||||
|
|
||||||
String firstName;
|
|
||||||
|
|
||||||
String id;
|
|
||||||
|
|
||||||
String lastName;
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) => identical(this, other) || other is AdminSignupResponseDto &&
|
|
||||||
other.createdAt == createdAt &&
|
|
||||||
other.email == email &&
|
|
||||||
other.firstName == firstName &&
|
|
||||||
other.id == id &&
|
|
||||||
other.lastName == lastName;
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode =>
|
|
||||||
// ignore: unnecessary_parenthesis
|
|
||||||
(createdAt.hashCode) +
|
|
||||||
(email.hashCode) +
|
|
||||||
(firstName.hashCode) +
|
|
||||||
(id.hashCode) +
|
|
||||||
(lastName.hashCode);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => 'AdminSignupResponseDto[createdAt=$createdAt, email=$email, firstName=$firstName, id=$id, lastName=$lastName]';
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
final json = <String, dynamic>{};
|
|
||||||
json[r'createdAt'] = this.createdAt.toUtc().toIso8601String();
|
|
||||||
json[r'email'] = this.email;
|
|
||||||
json[r'firstName'] = this.firstName;
|
|
||||||
json[r'id'] = this.id;
|
|
||||||
json[r'lastName'] = this.lastName;
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a new [AdminSignupResponseDto] instance and imports its values from
|
|
||||||
/// [value] if it's a [Map], null otherwise.
|
|
||||||
// ignore: prefer_constructors_over_static_methods
|
|
||||||
static AdminSignupResponseDto? fromJson(dynamic value) {
|
|
||||||
if (value is Map) {
|
|
||||||
final json = value.cast<String, dynamic>();
|
|
||||||
|
|
||||||
return AdminSignupResponseDto(
|
|
||||||
createdAt: mapDateTime(json, r'createdAt', '')!,
|
|
||||||
email: mapValueOfType<String>(json, r'email')!,
|
|
||||||
firstName: mapValueOfType<String>(json, r'firstName')!,
|
|
||||||
id: mapValueOfType<String>(json, r'id')!,
|
|
||||||
lastName: mapValueOfType<String>(json, r'lastName')!,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<AdminSignupResponseDto> listFromJson(dynamic json, {bool growable = false,}) {
|
|
||||||
final result = <AdminSignupResponseDto>[];
|
|
||||||
if (json is List && json.isNotEmpty) {
|
|
||||||
for (final row in json) {
|
|
||||||
final value = AdminSignupResponseDto.fromJson(row);
|
|
||||||
if (value != null) {
|
|
||||||
result.add(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result.toList(growable: growable);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Map<String, AdminSignupResponseDto> mapFromJson(dynamic json) {
|
|
||||||
final map = <String, AdminSignupResponseDto>{};
|
|
||||||
if (json is Map && json.isNotEmpty) {
|
|
||||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
|
||||||
for (final entry in json.entries) {
|
|
||||||
final value = AdminSignupResponseDto.fromJson(entry.value);
|
|
||||||
if (value != null) {
|
|
||||||
map[entry.key] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
// maps a json object with a list of AdminSignupResponseDto-objects as value to a dart map
|
|
||||||
static Map<String, List<AdminSignupResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
|
||||||
final map = <String, List<AdminSignupResponseDto>>{};
|
|
||||||
if (json is Map && json.isNotEmpty) {
|
|
||||||
// ignore: parameter_assignments
|
|
||||||
json = json.cast<String, dynamic>();
|
|
||||||
for (final entry in json.entries) {
|
|
||||||
map[entry.key] = AdminSignupResponseDto.listFromJson(entry.value, growable: growable,);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The list of required keys that must be present in a JSON.
|
|
||||||
static const requiredKeys = <String>{
|
|
||||||
'createdAt',
|
|
||||||
'email',
|
|
||||||
'firstName',
|
|
||||||
'id',
|
|
||||||
'lastName',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
|||||||
//
|
|
||||||
// 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 AdminSignupResponseDto
|
|
||||||
void main() {
|
|
||||||
// final instance = AdminSignupResponseDto();
|
|
||||||
|
|
||||||
group('test AdminSignupResponseDto', () {
|
|
||||||
// DateTime createdAt
|
|
||||||
test('to test the property `createdAt`', () async {
|
|
||||||
// TODO
|
|
||||||
});
|
|
||||||
|
|
||||||
// String email
|
|
||||||
test('to test the property `email`', () async {
|
|
||||||
// TODO
|
|
||||||
});
|
|
||||||
|
|
||||||
// String firstName
|
|
||||||
test('to test the property `firstName`', () async {
|
|
||||||
// TODO
|
|
||||||
});
|
|
||||||
|
|
||||||
// String id
|
|
||||||
test('to test the property `id`', () async {
|
|
||||||
// TODO
|
|
||||||
});
|
|
||||||
|
|
||||||
// String lastName
|
|
||||||
test('to test the property `lastName`', () async {
|
|
||||||
// TODO
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
2
mobile/openapi/test/authentication_api_test.dart
generated
2
mobile/openapi/test/authentication_api_test.dart
generated
@ -47,7 +47,7 @@ void main() {
|
|||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
|
|
||||||
//Future<AdminSignupResponseDto> signUpAdmin(SignUpDto signUpDto) async
|
//Future<UserResponseDto> signUpAdmin(SignUpDto signUpDto) async
|
||||||
test('test signUpAdmin', () async {
|
test('test signUpAdmin', () async {
|
||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
|
@ -2630,14 +2630,11 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/AdminSignupResponseDto"
|
"$ref": "#/components/schemas/UserResponseDto"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
|
||||||
"400": {
|
|
||||||
"description": "The server already has an admin"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -5812,34 +5809,6 @@
|
|||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"AdminSignupResponseDto": {
|
|
||||||
"properties": {
|
|
||||||
"createdAt": {
|
|
||||||
"format": "date-time",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"email": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"firstName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"id": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"lastName": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"id",
|
|
||||||
"email",
|
|
||||||
"firstName",
|
|
||||||
"lastName",
|
|
||||||
"createdAt"
|
|
||||||
],
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
"AlbumCountResponseDto": {
|
"AlbumCountResponseDto": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"notShared": {
|
"notShared": {
|
||||||
@ -7377,35 +7346,27 @@
|
|||||||
"LoginResponseDto": {
|
"LoginResponseDto": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"accessToken": {
|
"accessToken": {
|
||||||
"readOnly": true,
|
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"firstName": {
|
"firstName": {
|
||||||
"readOnly": true,
|
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"isAdmin": {
|
"isAdmin": {
|
||||||
"readOnly": true,
|
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"lastName": {
|
"lastName": {
|
||||||
"readOnly": true,
|
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"profileImagePath": {
|
"profileImagePath": {
|
||||||
"readOnly": true,
|
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"shouldChangePassword": {
|
"shouldChangePassword": {
|
||||||
"readOnly": true,
|
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"userEmail": {
|
"userEmail": {
|
||||||
"readOnly": true,
|
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"userId": {
|
"userId": {
|
||||||
"readOnly": true,
|
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
132
server/src/domain/auth/auth.dto.ts
Normal file
132
server/src/domain/auth/auth.dto.ts
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
import { UserEntity, UserTokenEntity } from '@app/infra/entities';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { Transform } from 'class-transformer';
|
||||||
|
import { IsEmail, IsNotEmpty, IsString, MinLength } from 'class-validator';
|
||||||
|
|
||||||
|
export class AuthUserDto {
|
||||||
|
id!: string;
|
||||||
|
email!: string;
|
||||||
|
isAdmin!: boolean;
|
||||||
|
isPublicUser?: boolean;
|
||||||
|
sharedLinkId?: string;
|
||||||
|
isAllowUpload?: boolean;
|
||||||
|
isAllowDownload?: boolean;
|
||||||
|
isShowMetadata?: boolean;
|
||||||
|
accessTokenId?: string;
|
||||||
|
externalPath?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LoginCredentialDto {
|
||||||
|
@IsEmail({ require_tld: false })
|
||||||
|
@Transform(({ value }) => value?.toLowerCase())
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({ example: 'testuser@email.com' })
|
||||||
|
email!: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({ example: 'password' })
|
||||||
|
password!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LoginResponseDto {
|
||||||
|
accessToken!: string;
|
||||||
|
userId!: string;
|
||||||
|
userEmail!: string;
|
||||||
|
firstName!: string;
|
||||||
|
lastName!: string;
|
||||||
|
profileImagePath!: string;
|
||||||
|
isAdmin!: boolean;
|
||||||
|
shouldChangePassword!: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapLoginResponse(entity: UserEntity, accessToken: string): LoginResponseDto {
|
||||||
|
return {
|
||||||
|
accessToken: accessToken,
|
||||||
|
userId: entity.id,
|
||||||
|
userEmail: entity.email,
|
||||||
|
firstName: entity.firstName,
|
||||||
|
lastName: entity.lastName,
|
||||||
|
isAdmin: entity.isAdmin,
|
||||||
|
profileImagePath: entity.profileImagePath,
|
||||||
|
shouldChangePassword: entity.shouldChangePassword,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LogoutResponseDto {
|
||||||
|
successful!: boolean;
|
||||||
|
redirectUri!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SignUpDto extends LoginCredentialDto {
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({ example: 'Admin' })
|
||||||
|
firstName!: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({ example: 'Doe' })
|
||||||
|
lastName!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ChangePasswordDto {
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({ example: 'password' })
|
||||||
|
password!: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
@MinLength(8)
|
||||||
|
@ApiProperty({ example: 'password' })
|
||||||
|
newPassword!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ValidateAccessTokenResponseDto {
|
||||||
|
authStatus!: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AuthDeviceResponseDto {
|
||||||
|
id!: string;
|
||||||
|
createdAt!: string;
|
||||||
|
updatedAt!: string;
|
||||||
|
current!: boolean;
|
||||||
|
deviceType!: string;
|
||||||
|
deviceOS!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mapUserToken = (entity: UserTokenEntity, currentId?: string): AuthDeviceResponseDto => ({
|
||||||
|
id: entity.id,
|
||||||
|
createdAt: entity.createdAt.toISOString(),
|
||||||
|
updatedAt: entity.updatedAt.toISOString(),
|
||||||
|
current: currentId === entity.id,
|
||||||
|
deviceOS: entity.deviceOS,
|
||||||
|
deviceType: entity.deviceType,
|
||||||
|
});
|
||||||
|
|
||||||
|
export class OAuthCallbackDto {
|
||||||
|
@IsNotEmpty()
|
||||||
|
@IsString()
|
||||||
|
@ApiProperty()
|
||||||
|
url!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class OAuthConfigDto {
|
||||||
|
@IsNotEmpty()
|
||||||
|
@IsString()
|
||||||
|
redirectUri!: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @deprecated use oauth authorize */
|
||||||
|
export class OAuthConfigResponseDto {
|
||||||
|
enabled!: boolean;
|
||||||
|
passwordLoginEnabled!: boolean;
|
||||||
|
url?: string;
|
||||||
|
buttonText?: string;
|
||||||
|
autoLaunch?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class OAuthAuthorizeResponseDto {
|
||||||
|
url!: string;
|
||||||
|
}
|
@ -31,8 +31,8 @@ import {
|
|||||||
IUserTokenRepository,
|
IUserTokenRepository,
|
||||||
} from '../repositories';
|
} from '../repositories';
|
||||||
import { AuthType } from './auth.constant';
|
import { AuthType } from './auth.constant';
|
||||||
|
import { AuthUserDto, SignUpDto } from './auth.dto';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { AuthUserDto, SignUpDto } from './dto';
|
|
||||||
|
|
||||||
// const token = Buffer.from('my-api-key', 'utf8').toString('base64');
|
// const token = Buffer.from('my-api-key', 'utf8').toString('base64');
|
||||||
|
|
||||||
|
@ -32,18 +32,21 @@ import {
|
|||||||
LOGIN_URL,
|
LOGIN_URL,
|
||||||
MOBILE_REDIRECT,
|
MOBILE_REDIRECT,
|
||||||
} from './auth.constant';
|
} from './auth.constant';
|
||||||
import { AuthUserDto, ChangePasswordDto, LoginCredentialDto, OAuthCallbackDto, OAuthConfigDto, SignUpDto } from './dto';
|
|
||||||
import {
|
import {
|
||||||
AdminSignupResponseDto,
|
|
||||||
AuthDeviceResponseDto,
|
AuthDeviceResponseDto,
|
||||||
|
AuthUserDto,
|
||||||
|
ChangePasswordDto,
|
||||||
|
LoginCredentialDto,
|
||||||
LoginResponseDto,
|
LoginResponseDto,
|
||||||
LogoutResponseDto,
|
LogoutResponseDto,
|
||||||
OAuthAuthorizeResponseDto,
|
OAuthAuthorizeResponseDto,
|
||||||
|
OAuthCallbackDto,
|
||||||
|
OAuthConfigDto,
|
||||||
OAuthConfigResponseDto,
|
OAuthConfigResponseDto,
|
||||||
mapAdminSignupResponse,
|
SignUpDto,
|
||||||
mapLoginResponse,
|
mapLoginResponse,
|
||||||
mapUserToken,
|
mapUserToken,
|
||||||
} from './response-dto';
|
} from './auth.dto';
|
||||||
|
|
||||||
export interface LoginDetails {
|
export interface LoginDetails {
|
||||||
isSecure: boolean;
|
isSecure: boolean;
|
||||||
@ -133,7 +136,7 @@ export class AuthService {
|
|||||||
return this.userCore.updateUser(authUser, authUser.id, { password: newPassword });
|
return this.userCore.updateUser(authUser, authUser.id, { password: newPassword });
|
||||||
}
|
}
|
||||||
|
|
||||||
async adminSignUp(dto: SignUpDto): Promise<AdminSignupResponseDto> {
|
async adminSignUp(dto: SignUpDto): Promise<UserResponseDto> {
|
||||||
const adminUser = await this.userRepository.getAdmin();
|
const adminUser = await this.userRepository.getAdmin();
|
||||||
|
|
||||||
if (adminUser) {
|
if (adminUser) {
|
||||||
@ -149,7 +152,7 @@ export class AuthService {
|
|||||||
storageLabel: 'admin',
|
storageLabel: 'admin',
|
||||||
});
|
});
|
||||||
|
|
||||||
return mapAdminSignupResponse(admin);
|
return mapUser(admin);
|
||||||
}
|
}
|
||||||
|
|
||||||
async validate(headers: IncomingHttpHeaders, params: Record<string, string>): Promise<AuthUserDto> {
|
async validate(headers: IncomingHttpHeaders, params: Record<string, string>): Promise<AuthUserDto> {
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
export class AuthUserDto {
|
|
||||||
id!: string;
|
|
||||||
email!: string;
|
|
||||||
isAdmin!: boolean;
|
|
||||||
isPublicUser?: boolean;
|
|
||||||
sharedLinkId?: string;
|
|
||||||
isAllowUpload?: boolean;
|
|
||||||
isAllowDownload?: boolean;
|
|
||||||
isShowMetadata?: boolean;
|
|
||||||
accessTokenId?: string;
|
|
||||||
externalPath?: string | null;
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger';
|
|
||||||
import { IsNotEmpty, IsString, MinLength } from 'class-validator';
|
|
||||||
|
|
||||||
export class ChangePasswordDto {
|
|
||||||
@IsString()
|
|
||||||
@IsNotEmpty()
|
|
||||||
@ApiProperty({ example: 'password' })
|
|
||||||
password!: string;
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsNotEmpty()
|
|
||||||
@MinLength(8)
|
|
||||||
@ApiProperty({ example: 'password' })
|
|
||||||
newPassword!: string;
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
export * from './auth-user.dto';
|
|
||||||
export * from './change-password.dto';
|
|
||||||
export * from './login-credential.dto';
|
|
||||||
export * from './oauth-auth-code.dto';
|
|
||||||
export * from './oauth-config.dto';
|
|
||||||
export * from './sign-up.dto';
|
|
@ -1,42 +0,0 @@
|
|||||||
import { plainToInstance } from 'class-transformer';
|
|
||||||
import { validateSync } from 'class-validator';
|
|
||||||
import { LoginCredentialDto } from './login-credential.dto';
|
|
||||||
|
|
||||||
describe('LoginCredentialDto', () => {
|
|
||||||
it('should allow emails without a tld', () => {
|
|
||||||
const someEmail = 'test@test';
|
|
||||||
|
|
||||||
const dto = plainToInstance(LoginCredentialDto, { email: someEmail, password: 'password' });
|
|
||||||
const errors = validateSync(dto);
|
|
||||||
expect(errors).toHaveLength(0);
|
|
||||||
expect(dto.email).toEqual(someEmail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fail without an email', () => {
|
|
||||||
const dto = plainToInstance(LoginCredentialDto, { password: 'password' });
|
|
||||||
const errors = validateSync(dto);
|
|
||||||
expect(errors).toHaveLength(1);
|
|
||||||
expect(errors[0].property).toEqual('email');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fail with an invalid email', () => {
|
|
||||||
const dto = plainToInstance(LoginCredentialDto, { email: 'invalid.com', password: 'password' });
|
|
||||||
const errors = validateSync(dto);
|
|
||||||
expect(errors).toHaveLength(1);
|
|
||||||
expect(errors[0].property).toEqual('email');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should make the email all lowercase', () => {
|
|
||||||
const dto = plainToInstance(LoginCredentialDto, { email: 'TeSt@ImMiCh.com', password: 'password' });
|
|
||||||
const errors = validateSync(dto);
|
|
||||||
expect(errors).toHaveLength(0);
|
|
||||||
expect(dto.email).toEqual('test@immich.com');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fail without a password', () => {
|
|
||||||
const dto = plainToInstance(LoginCredentialDto, { email: 'test@immich.com', password: '' });
|
|
||||||
const errors = validateSync(dto);
|
|
||||||
expect(errors).toHaveLength(1);
|
|
||||||
expect(errors[0].property).toEqual('password');
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,16 +0,0 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger';
|
|
||||||
import { Transform } from 'class-transformer';
|
|
||||||
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
|
|
||||||
|
|
||||||
export class LoginCredentialDto {
|
|
||||||
@IsEmail({ require_tld: false })
|
|
||||||
@Transform(({ value }) => value?.toLowerCase())
|
|
||||||
@IsNotEmpty()
|
|
||||||
@ApiProperty({ example: 'testuser@email.com' })
|
|
||||||
email!: string;
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsNotEmpty()
|
|
||||||
@ApiProperty({ example: 'password' })
|
|
||||||
password!: string;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger';
|
|
||||||
import { IsNotEmpty, IsString } from 'class-validator';
|
|
||||||
|
|
||||||
export class OAuthCallbackDto {
|
|
||||||
@IsNotEmpty()
|
|
||||||
@IsString()
|
|
||||||
@ApiProperty()
|
|
||||||
url!: string;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
import { IsNotEmpty, IsString } from 'class-validator';
|
|
||||||
|
|
||||||
export class OAuthConfigDto {
|
|
||||||
@IsNotEmpty()
|
|
||||||
@IsString()
|
|
||||||
redirectUri!: string;
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
import { plainToInstance } from 'class-transformer';
|
|
||||||
import { validateSync } from 'class-validator';
|
|
||||||
import { SignUpDto } from './sign-up.dto';
|
|
||||||
|
|
||||||
describe('SignUpDto', () => {
|
|
||||||
it('should require all fields', () => {
|
|
||||||
const dto = plainToInstance(SignUpDto, {
|
|
||||||
email: '',
|
|
||||||
password: '',
|
|
||||||
firstName: '',
|
|
||||||
lastName: '',
|
|
||||||
});
|
|
||||||
const errors = validateSync(dto);
|
|
||||||
expect(errors).toHaveLength(4);
|
|
||||||
expect(errors[0].property).toEqual('email');
|
|
||||||
expect(errors[1].property).toEqual('password');
|
|
||||||
expect(errors[2].property).toEqual('firstName');
|
|
||||||
expect(errors[3].property).toEqual('lastName');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid email', () => {
|
|
||||||
const dto = plainToInstance(SignUpDto, {
|
|
||||||
email: 'immich.com',
|
|
||||||
password: 'password',
|
|
||||||
firstName: 'first name',
|
|
||||||
lastName: 'last name',
|
|
||||||
});
|
|
||||||
const errors = validateSync(dto);
|
|
||||||
expect(errors).toHaveLength(1);
|
|
||||||
expect(errors[0].property).toEqual('email');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should allow emails without a tld', () => {
|
|
||||||
const someEmail = 'test@test';
|
|
||||||
|
|
||||||
const dto = plainToInstance(SignUpDto, {
|
|
||||||
email: someEmail,
|
|
||||||
password: 'password',
|
|
||||||
firstName: 'first name',
|
|
||||||
lastName: 'last name',
|
|
||||||
});
|
|
||||||
const errors = validateSync(dto);
|
|
||||||
expect(errors).toHaveLength(0);
|
|
||||||
expect(dto.email).toEqual(someEmail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should make the email all lowercase', () => {
|
|
||||||
const dto = plainToInstance(SignUpDto, {
|
|
||||||
email: 'TeSt@ImMiCh.com',
|
|
||||||
password: 'password',
|
|
||||||
firstName: 'first name',
|
|
||||||
lastName: 'last name',
|
|
||||||
});
|
|
||||||
const errors = validateSync(dto);
|
|
||||||
expect(errors).toHaveLength(0);
|
|
||||||
expect(dto.email).toEqual('test@immich.com');
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,26 +0,0 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger';
|
|
||||||
import { Transform } from 'class-transformer';
|
|
||||||
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
|
|
||||||
|
|
||||||
export class SignUpDto {
|
|
||||||
@IsEmail({ require_tld: false })
|
|
||||||
@Transform(({ value }) => value?.toLowerCase())
|
|
||||||
@IsNotEmpty()
|
|
||||||
@ApiProperty({ example: 'testuser@email.com' })
|
|
||||||
email!: string;
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsNotEmpty()
|
|
||||||
@ApiProperty({ example: 'password' })
|
|
||||||
password!: string;
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsNotEmpty()
|
|
||||||
@ApiProperty({ example: 'Admin' })
|
|
||||||
firstName!: string;
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsNotEmpty()
|
|
||||||
@ApiProperty({ example: 'Doe' })
|
|
||||||
lastName!: string;
|
|
||||||
}
|
|
@ -1,4 +1,3 @@
|
|||||||
export * from './auth.constant';
|
export * from './auth.constant';
|
||||||
|
export * from './auth.dto';
|
||||||
export * from './auth.service';
|
export * from './auth.service';
|
||||||
export * from './dto';
|
|
||||||
export * from './response-dto';
|
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
import { UserEntity } from '@app/infra/entities';
|
|
||||||
|
|
||||||
export class AdminSignupResponseDto {
|
|
||||||
id!: string;
|
|
||||||
email!: string;
|
|
||||||
firstName!: string;
|
|
||||||
lastName!: string;
|
|
||||||
createdAt!: Date;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapAdminSignupResponse(entity: UserEntity): AdminSignupResponseDto {
|
|
||||||
return {
|
|
||||||
id: entity.id,
|
|
||||||
email: entity.email,
|
|
||||||
firstName: entity.firstName,
|
|
||||||
lastName: entity.lastName,
|
|
||||||
createdAt: entity.createdAt,
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
import { UserTokenEntity } from '@app/infra/entities';
|
|
||||||
|
|
||||||
export class AuthDeviceResponseDto {
|
|
||||||
id!: string;
|
|
||||||
createdAt!: string;
|
|
||||||
updatedAt!: string;
|
|
||||||
current!: boolean;
|
|
||||||
deviceType!: string;
|
|
||||||
deviceOS!: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const mapUserToken = (entity: UserTokenEntity, currentId?: string): AuthDeviceResponseDto => ({
|
|
||||||
id: entity.id,
|
|
||||||
createdAt: entity.createdAt.toISOString(),
|
|
||||||
updatedAt: entity.updatedAt.toISOString(),
|
|
||||||
current: currentId === entity.id,
|
|
||||||
deviceOS: entity.deviceOS,
|
|
||||||
deviceType: entity.deviceType,
|
|
||||||
});
|
|
@ -1,6 +0,0 @@
|
|||||||
export * from './admin-signup-response.dto';
|
|
||||||
export * from './auth-device-response.dto';
|
|
||||||
export * from './login-response.dto';
|
|
||||||
export * from './logout-response.dto';
|
|
||||||
export * from './oauth-config-response.dto';
|
|
||||||
export * from './validate-asset-token-response.dto';
|
|
@ -1,41 +0,0 @@
|
|||||||
import { UserEntity } from '@app/infra/entities';
|
|
||||||
import { ApiResponseProperty } from '@nestjs/swagger';
|
|
||||||
|
|
||||||
export class LoginResponseDto {
|
|
||||||
@ApiResponseProperty()
|
|
||||||
accessToken!: string;
|
|
||||||
|
|
||||||
@ApiResponseProperty()
|
|
||||||
userId!: string;
|
|
||||||
|
|
||||||
@ApiResponseProperty()
|
|
||||||
userEmail!: string;
|
|
||||||
|
|
||||||
@ApiResponseProperty()
|
|
||||||
firstName!: string;
|
|
||||||
|
|
||||||
@ApiResponseProperty()
|
|
||||||
lastName!: string;
|
|
||||||
|
|
||||||
@ApiResponseProperty()
|
|
||||||
profileImagePath!: string;
|
|
||||||
|
|
||||||
@ApiResponseProperty()
|
|
||||||
isAdmin!: boolean;
|
|
||||||
|
|
||||||
@ApiResponseProperty()
|
|
||||||
shouldChangePassword!: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapLoginResponse(entity: UserEntity, accessToken: string): LoginResponseDto {
|
|
||||||
return {
|
|
||||||
accessToken: accessToken,
|
|
||||||
userId: entity.id,
|
|
||||||
userEmail: entity.email,
|
|
||||||
firstName: entity.firstName,
|
|
||||||
lastName: entity.lastName,
|
|
||||||
isAdmin: entity.isAdmin,
|
|
||||||
profileImagePath: entity.profileImagePath,
|
|
||||||
shouldChangePassword: entity.shouldChangePassword,
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
export class LogoutResponseDto {
|
|
||||||
successful!: boolean;
|
|
||||||
redirectUri!: string;
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
export class OAuthConfigResponseDto {
|
|
||||||
enabled!: boolean;
|
|
||||||
passwordLoginEnabled!: boolean;
|
|
||||||
url?: string;
|
|
||||||
buttonText?: string;
|
|
||||||
autoLaunch?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class OAuthAuthorizeResponseDto {
|
|
||||||
url!: string;
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
export class ValidateAccessTokenResponseDto {
|
|
||||||
authStatus!: boolean;
|
|
||||||
}
|
|
@ -1,5 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
AdminSignupResponseDto,
|
|
||||||
AuthDeviceResponseDto,
|
AuthDeviceResponseDto,
|
||||||
AuthService,
|
AuthService,
|
||||||
AuthUserDto,
|
AuthUserDto,
|
||||||
@ -15,7 +14,7 @@ import {
|
|||||||
ValidateAccessTokenResponseDto,
|
ValidateAccessTokenResponseDto,
|
||||||
} from '@app/domain';
|
} from '@app/domain';
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Req, Res } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Req, Res } from '@nestjs/common';
|
||||||
import { ApiBadRequestResponse, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { AuthUser, Authenticated, GetLoginDetails, PublicRoute } from '../app.guard';
|
import { AuthUser, Authenticated, GetLoginDetails, PublicRoute } from '../app.guard';
|
||||||
import { UseValidation } from '../app.utils';
|
import { UseValidation } from '../app.utils';
|
||||||
@ -42,9 +41,8 @@ export class AuthController {
|
|||||||
|
|
||||||
@PublicRoute()
|
@PublicRoute()
|
||||||
@Post('admin-sign-up')
|
@Post('admin-sign-up')
|
||||||
@ApiBadRequestResponse({ description: 'The server already has an admin' })
|
signUpAdmin(@Body() dto: SignUpDto): Promise<UserResponseDto> {
|
||||||
signUpAdmin(@Body() signUpCredential: SignUpDto): Promise<AdminSignupResponseDto> {
|
return this.service.adminSignUp(dto);
|
||||||
return this.service.adminSignUp(signUpCredential);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('devices')
|
@Get('devices')
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { AdminSignupResponseDto, AuthDeviceResponseDto, LoginCredentialDto, LoginResponseDto } from '@app/domain';
|
import { AuthDeviceResponseDto, LoginCredentialDto, LoginResponseDto, UserResponseDto } from '@app/domain';
|
||||||
import { adminSignupStub, loginResponseStub, loginStub, signupResponseStub } from '@test';
|
import { adminSignupStub, loginResponseStub, loginStub } from '@test';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
|
|
||||||
export const authApi = {
|
export const authApi = {
|
||||||
@ -7,9 +7,8 @@ export const authApi = {
|
|||||||
const { status, body } = await request(server).post('/auth/admin-sign-up').send(adminSignupStub);
|
const { status, body } = await request(server).post('/auth/admin-sign-up').send(adminSignupStub);
|
||||||
|
|
||||||
expect(status).toBe(201);
|
expect(status).toBe(201);
|
||||||
expect(body).toEqual(signupResponseStub);
|
|
||||||
|
|
||||||
return body as AdminSignupResponseDto;
|
return body as UserResponseDto;
|
||||||
},
|
},
|
||||||
adminLogin: async (server: any) => {
|
adminLogin: async (server: any) => {
|
||||||
const { status, body } = await request(server).post('/auth/login').send(loginStub.admin);
|
const { status, body } = await request(server).post('/auth/login').send(loginStub.admin);
|
||||||
|
@ -8,7 +8,6 @@ import {
|
|||||||
errorStub,
|
errorStub,
|
||||||
loginResponseStub,
|
loginResponseStub,
|
||||||
loginStub,
|
loginStub,
|
||||||
signupResponseStub,
|
|
||||||
uuidStub,
|
uuidStub,
|
||||||
} from '@test/fixtures';
|
} from '@test/fixtures';
|
||||||
import { testApp } from '@test/test-utils';
|
import { testApp } from '@test/test-utils';
|
||||||
@ -19,6 +18,24 @@ const lastName = 'Admin';
|
|||||||
const password = 'Password123';
|
const password = 'Password123';
|
||||||
const email = 'admin@immich.app';
|
const email = 'admin@immich.app';
|
||||||
|
|
||||||
|
const adminSignupResponse = {
|
||||||
|
id: expect.any(String),
|
||||||
|
firstName: 'Immich',
|
||||||
|
lastName: 'Admin',
|
||||||
|
email: 'admin@immich.app',
|
||||||
|
storageLabel: 'admin',
|
||||||
|
externalPath: null,
|
||||||
|
profileImagePath: '',
|
||||||
|
// why? lol
|
||||||
|
shouldChangePassword: true,
|
||||||
|
isAdmin: true,
|
||||||
|
createdAt: expect.any(String),
|
||||||
|
updatedAt: expect.any(String),
|
||||||
|
deletedAt: null,
|
||||||
|
oauthId: '',
|
||||||
|
memoriesEnabled: true,
|
||||||
|
};
|
||||||
|
|
||||||
describe(`${AuthController.name} (e2e)`, () => {
|
describe(`${AuthController.name} (e2e)`, () => {
|
||||||
let server: any;
|
let server: any;
|
||||||
let accessToken: string;
|
let accessToken: string;
|
||||||
@ -84,7 +101,7 @@ describe(`${AuthController.name} (e2e)`, () => {
|
|||||||
.post('/auth/admin-sign-up')
|
.post('/auth/admin-sign-up')
|
||||||
.send({ ...adminSignupStub, email: 'admin@local' });
|
.send({ ...adminSignupStub, email: 'admin@local' });
|
||||||
expect(status).toEqual(201);
|
expect(status).toEqual(201);
|
||||||
expect(body).toEqual({ ...signupResponseStub, email: 'admin@local' });
|
expect(body).toEqual({ ...adminSignupResponse, email: 'admin@local' });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should transform email to lower case', async () => {
|
it('should transform email to lower case', async () => {
|
||||||
@ -92,7 +109,7 @@ describe(`${AuthController.name} (e2e)`, () => {
|
|||||||
.post('/auth/admin-sign-up')
|
.post('/auth/admin-sign-up')
|
||||||
.send({ ...adminSignupStub, email: 'aDmIn@IMMICH.app' });
|
.send({ ...adminSignupStub, email: 'aDmIn@IMMICH.app' });
|
||||||
expect(status).toEqual(201);
|
expect(status).toEqual(201);
|
||||||
expect(body).toEqual(signupResponseStub);
|
expect(body).toEqual(adminSignupResponse);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not allow a second admin to sign up', async () => {
|
it('should not allow a second admin to sign up', async () => {
|
||||||
|
8
server/test/fixtures/auth.stub.ts
vendored
8
server/test/fixtures/auth.stub.ts
vendored
@ -12,14 +12,6 @@ export const userSignupStub = {
|
|||||||
memoriesEnabled: true,
|
memoriesEnabled: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const signupResponseStub = {
|
|
||||||
id: expect.any(String),
|
|
||||||
email: 'admin@immich.app',
|
|
||||||
firstName: 'Immich',
|
|
||||||
lastName: 'Admin',
|
|
||||||
createdAt: expect.any(String),
|
|
||||||
};
|
|
||||||
|
|
||||||
export const loginStub = {
|
export const loginStub = {
|
||||||
admin: {
|
admin: {
|
||||||
email: 'admin@immich.app',
|
email: 'admin@immich.app',
|
||||||
|
41
web/src/api/open-api/api.ts
generated
41
web/src/api/open-api/api.ts
generated
@ -209,43 +209,6 @@ export interface AddUsersDto {
|
|||||||
*/
|
*/
|
||||||
'sharedUserIds': Array<string>;
|
'sharedUserIds': Array<string>;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface AdminSignupResponseDto
|
|
||||||
*/
|
|
||||||
export interface AdminSignupResponseDto {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof AdminSignupResponseDto
|
|
||||||
*/
|
|
||||||
'createdAt': string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof AdminSignupResponseDto
|
|
||||||
*/
|
|
||||||
'email': string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof AdminSignupResponseDto
|
|
||||||
*/
|
|
||||||
'firstName': string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof AdminSignupResponseDto
|
|
||||||
*/
|
|
||||||
'id': string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof AdminSignupResponseDto
|
|
||||||
*/
|
|
||||||
'lastName': string;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
@ -10509,7 +10472,7 @@ export const AuthenticationApiFp = function(configuration?: Configuration) {
|
|||||||
* @param {*} [options] Override http request option.
|
* @param {*} [options] Override http request option.
|
||||||
* @throws {RequiredError}
|
* @throws {RequiredError}
|
||||||
*/
|
*/
|
||||||
async signUpAdmin(signUpDto: SignUpDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AdminSignupResponseDto>> {
|
async signUpAdmin(signUpDto: SignUpDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<UserResponseDto>> {
|
||||||
const localVarAxiosArgs = await localVarAxiosParamCreator.signUpAdmin(signUpDto, options);
|
const localVarAxiosArgs = await localVarAxiosParamCreator.signUpAdmin(signUpDto, options);
|
||||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||||
},
|
},
|
||||||
@ -10589,7 +10552,7 @@ export const AuthenticationApiFactory = function (configuration?: Configuration,
|
|||||||
* @param {*} [options] Override http request option.
|
* @param {*} [options] Override http request option.
|
||||||
* @throws {RequiredError}
|
* @throws {RequiredError}
|
||||||
*/
|
*/
|
||||||
signUpAdmin(requestParameters: AuthenticationApiSignUpAdminRequest, options?: AxiosRequestConfig): AxiosPromise<AdminSignupResponseDto> {
|
signUpAdmin(requestParameters: AuthenticationApiSignUpAdminRequest, options?: AxiosRequestConfig): AxiosPromise<UserResponseDto> {
|
||||||
return localVarFp.signUpAdmin(requestParameters.signUpDto, options).then((request) => request(axios, basePath));
|
return localVarFp.signUpAdmin(requestParameters.signUpDto, options).then((request) => request(axios, basePath));
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user