feat(server): move authentication to tokens stored in the database (#1381)

* chore: add typeorm commands to npm and set default database config values

* feat: move to server side authentication tokens

* fix: websocket should emit error and disconnect on error thrown by the server

* refactor: rename cookie-auth-strategy to user-auth-strategy

* feat: user tokens and API keys now use SHA256 hash for performance improvements

* test: album e2e test remove unneeded module import

* infra: truncate api key table as old keys will no longer work with new hash algorithm

* fix(server): e2e tests (#1435)

* fix: root module paths

* chore: linting

* chore: rename user-auth to strategy.ts and make validate return AuthUserDto

* fix: we should always send HttpOnly for our auth cookies

* chore: remove now unused crypto functions and jwt dependencies

* fix: return the extra fields for AuthUserDto in auth service validate

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
Zack Pollard
2023-01-27 20:50:07 +00:00
committed by GitHub
parent 9be71f603e
commit 3f2513a717
61 changed files with 373 additions and 517 deletions

View File

@@ -1,4 +1,11 @@
import { AssetType, SharedLinkEntity, SharedLinkType, SystemConfig, UserEntity } from '@app/infra/db/entities';
import {
AssetType,
SharedLinkEntity,
SharedLinkType,
SystemConfig,
UserEntity,
UserTokenEntity,
} from '@app/infra/db/entities';
import { AlbumResponseDto, AssetResponseDto, AuthUserDto, ExifResponseDto, SharedLinkResponseDto } from '../src';
const today = new Date();
@@ -81,6 +88,8 @@ export const authStub = {
isAdmin: false,
isPublicUser: false,
isAllowUpload: true,
isAllowDownload: true,
isShowExif: true,
}),
adminSharedLink: Object.freeze<AuthUserDto>({
id: 'admin_id',
@@ -104,7 +113,7 @@ export const authStub = {
}),
};
export const entityStub = {
export const userEntityStub = {
admin: Object.freeze<UserEntity>({
...authStub.admin,
password: 'admin_password',
@@ -129,6 +138,16 @@ export const entityStub = {
}),
};
export const userTokenEntityStub = {
userToken: Object.freeze<UserTokenEntity>({
id: 'token-id',
token: 'auth_token',
user: userEntityStub.user1,
createdAt: '2021-01-01',
updatedAt: '2021-01-01',
}),
};
export const systemConfigStub = {
defaults: Object.freeze({
ffmpeg: {
@@ -204,7 +223,7 @@ export const systemConfigStub = {
export const loginResponseStub = {
user1oauth: {
response: {
accessToken: 'signed-jwt',
accessToken: 'cmFuZG9tLWJ5dGVz',
userId: 'immich_id',
userEmail: 'immich@test.com',
firstName: 'immich_first_name',
@@ -214,13 +233,13 @@ export const loginResponseStub = {
shouldChangePassword: false,
},
cookie: [
'immich_access_token=signed-jwt; Secure; Path=/; Max-Age=604800; SameSite=Strict;',
'immich_auth_type=oauth; Secure; Path=/; Max-Age=604800; SameSite=Strict;',
'immich_access_token=cmFuZG9tLWJ5dGVz; HttpOnly; Secure; Path=/; Max-Age=604800; SameSite=Strict;',
'immich_auth_type=oauth; HttpOnly; Secure; Path=/; Max-Age=604800; SameSite=Strict;',
],
},
user1password: {
response: {
accessToken: 'signed-jwt',
accessToken: 'cmFuZG9tLWJ5dGVz',
userId: 'immich_id',
userEmail: 'immich@test.com',
firstName: 'immich_first_name',
@@ -230,13 +249,13 @@ export const loginResponseStub = {
shouldChangePassword: false,
},
cookie: [
'immich_access_token=signed-jwt; Secure; Path=/; Max-Age=604800; SameSite=Strict;',
'immich_auth_type=password; Secure; Path=/; Max-Age=604800; SameSite=Strict;',
'immich_access_token=cmFuZG9tLWJ5dGVz; HttpOnly; Secure; Path=/; Max-Age=604800; SameSite=Strict;',
'immich_auth_type=password; HttpOnly; Secure; Path=/; Max-Age=604800; SameSite=Strict;',
],
},
user1insecure: {
response: {
accessToken: 'signed-jwt',
accessToken: 'cmFuZG9tLWJ5dGVz',
userId: 'immich_id',
userEmail: 'immich@test.com',
firstName: 'immich_first_name',
@@ -246,7 +265,7 @@ export const loginResponseStub = {
shouldChangePassword: false,
},
cookie: [
'immich_access_token=signed-jwt; HttpOnly; Path=/; Max-Age=604800; SameSite=Strict;',
'immich_access_token=cmFuZG9tLWJ5dGVz; HttpOnly; Path=/; Max-Age=604800; SameSite=Strict;',
'immich_auth_type=password; HttpOnly; Path=/; Max-Age=604800; SameSite=Strict;',
],
},