Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 7.0.0 #203

Merged
merged 5 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,37 @@
# GameVault Backend Server Changelog

## 7.0.0

Recommended Gamevault App Version: `v1.6.1`

### Breaking Changes & Migration

- Case Insensitivity for Usernames and Emails:

- Usernames and user emails are now treated as case-insensitive.
- During the update to v7.0.0, a new database migration will check for users with conflicting usernames or emails caused by differences in letter casing.
- If such conflicts are found, the migration will halt and report an error. This prevents the update to v7.0.0 until these conflicts are resolved.
- Administrators are advised to revert to the previous GameVault version to address these conflicts and ensure a smooth transition to v7.0.0.

- Performance Enhancement: Removal of Progress Details and Filters from /games API:

- To further enhance performance, the /games API no longer includes progress details and filters.

- Improved User Progress Handling:

- User-related calls now include deleted game details in their progress information.
- This enhancement allows for the correct display of progress even after a game has been deleted, ensuring a more comprehensive user experience.

### Changes

- Made Failing Game Downloads more robust
- Fixed missing indexation game type getting detected as difference

### Thanks

- @Kairubyte
- @MarshyMadness

## 6.0.0

Recommended Gamevault App Version: `v1.6.0`
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "gamevault-backend",
"version": "6.0.0",
"version": "7.0.0",
"description": "the self-hosted gaming platform for drm-free games",
"author": "Alkan Alper, Schäfer Philip GbR / Phalcode",
"private": true,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class CheckUserCaseConflicts1695686400000 implements MigrationInterface {
name?: string;
transaction?: boolean;

public async up(queryRunner: QueryRunner): Promise<void> {
// Check for conflicting users with different casing for username or email
const duplicateUsers = await queryRunner.query(`
SELECT u.username, u.email
FROM gamevault_user u
WHERE (LOWER(u.username), LOWER(u.email)) IN (
SELECT LOWER(username), LOWER(email)
FROM gamevault_user
GROUP BY LOWER(username), LOWER(email)
HAVING COUNT(*) > 1
);
`);

if (duplicateUsers.length > 0) {
throw new Error(
`User conflicts detected with different casing for username or email. Please roll back to GameVault Backend Version 6.0.0 and resolve the conflicts before updating to v7.0.0.\nConflicting Users: ${JSON.stringify(
duplicateUsers,
null,
2,
)}`,
);
}
}

public async down(): Promise<void> {
// This is a migration to check for conflicts; no need for a down operation
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class CheckUserCaseConflicts1695686400000 implements MigrationInterface {
name?: string;
transaction?: boolean;

public async up(queryRunner: QueryRunner): Promise<void> {
// Check for conflicting users with different casing for username or email
const duplicateUsers = await queryRunner.query(`
SELECT u.username, u.email
FROM gamevault_user u
WHERE (LOWER(u.username), LOWER(u.email)) IN (
SELECT LOWER(username), LOWER(email)
FROM gamevault_user
GROUP BY LOWER(username), LOWER(email)
HAVING COUNT(*) > 1
);
`);

if (duplicateUsers.length > 0) {
throw new Error(
`User conflicts detected with different casing for username or email. Please roll back to GameVault Backend version 6.0.0 and resolve the conflicts before updating to v7.0.0.\nConflicting Users: ${JSON.stringify(
duplicateUsers,
null,
2,
)}`,
);
}
}

public async down(): Promise<void> {
// This is a migration to check for conflicts; no need for a down operation
}
}
12 changes: 10 additions & 2 deletions src/modules/files/files.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
Injectable,
InternalServerErrorException,
Logger,
NotFoundException,
OnApplicationBootstrap,
StreamableFile,
} from "@nestjs/common";
Expand Down Expand Up @@ -346,10 +347,13 @@ export class FilesService implements OnApplicationBootstrap {

private async archiveFiles(
output: string,
source: string | string[],
sourcePath: string,
): Promise<void> {
if (!existsSync(sourcePath)) {
throw new NotFoundException(`The game file could not be found.`);
}
return new Promise<void>((resolve, reject) => {
const archiveStream = add(output, source);
const archiveStream = add(output, sourcePath);
archiveStream.on("error", (error) => {
this.logger.error(error, `Error archiving "${output}"`);
reject(error);
Expand Down Expand Up @@ -491,6 +495,10 @@ export class FilesService implements OnApplicationBootstrap {
}
}

if (!existsSync(fileDownloadPath)) {
throw new NotFoundException(`The game file could not be found.`);
}

const file = createReadStream(fileDownloadPath).pipe(
new Throttle(speedlimit),
);
Expand Down
6 changes: 1 addition & 5 deletions src/modules/games/games.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class GamesController {
defaultLimit: 100,
maxLimit: NO_PAGINATION,
nullSort: "last",
relations: ["progresses", "box_image"],
relations: ["box_image"],
sortableColumns: [
"id",
"title",
Expand All @@ -96,10 +96,6 @@ export class GamesController {
average_playtime: all_filters,
early_access: all_filters,
type: all_filters,
"progresses.created_at": all_filters,
"progresses.updated_at": all_filters,
"progresses.minutes_played": all_filters,
"progresses.state": all_filters,
},
withDeleted: false,
});
Expand Down
3 changes: 0 additions & 3 deletions src/modules/games/games.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,6 @@ export class GamesService {
`Early Access: ${foundGame.early_access} -> ${game.early_access}`,
);
}
if (foundGame.type !== game.type) {
differences.push(`Game Type: ${foundGame.type} -> ${game.type}`);
}
if (foundGame.version != game.version) {
differences.push(`Version: ${foundGame.version} -> ${game.version}`);
}
Expand Down
Loading