Implement 301 redirects for www to non-www and enhance canonical tag handling

This commit adds 301 redirects in the Apache configuration to redirect traffic from www.tt-tagebuch.de to tt-tagebuch.de for both HTTP and HTTPS. Additionally, it introduces middleware in the backend to dynamically set canonical tags based on the request URL, ensuring proper SEO practices. The request logging middleware has been disabled, and sensitive data handling has been improved in the MyTischtennis model and API logging service, ensuring compliance with data protection regulations. Frontend updates include enhanced descriptions and features in the application, improving user experience and clarity.
This commit is contained in:
Torsten Schulz (local)
2025-11-16 12:08:56 +01:00
parent de36a8ce2b
commit 5b04ed7904
12 changed files with 1201 additions and 146 deletions

View File

@@ -22,6 +22,14 @@ const MyTischtennis = sequelize.define('MyTischtennis', {
email: {
type: DataTypes.STRING,
allowNull: false,
set(value) {
const encryptedValue = encryptData(value);
this.setDataValue('email', encryptedValue);
},
get() {
const encryptedValue = this.getDataValue('email');
return decryptData(encryptedValue);
}
},
encryptedPassword: {
type: DataTypes.TEXT,
@@ -43,12 +51,38 @@ const MyTischtennis = sequelize.define('MyTischtennis', {
accessToken: {
type: DataTypes.TEXT,
allowNull: true,
field: 'access_token'
field: 'access_token',
set(value) {
if (value === null || value === undefined) {
this.setDataValue('accessToken', null);
} else {
const encryptedValue = encryptData(value);
this.setDataValue('accessToken', encryptedValue);
}
},
get() {
const encryptedValue = this.getDataValue('accessToken');
if (!encryptedValue) return null;
return decryptData(encryptedValue);
}
},
refreshToken: {
type: DataTypes.TEXT,
allowNull: true,
field: 'refresh_token'
field: 'refresh_token',
set(value) {
if (value === null || value === undefined) {
this.setDataValue('refreshToken', null);
} else {
const encryptedValue = encryptData(value);
this.setDataValue('refreshToken', encryptedValue);
}
},
get() {
const encryptedValue = this.getDataValue('refreshToken');
if (!encryptedValue) return null;
return decryptData(encryptedValue);
}
},
expiresAt: {
type: DataTypes.BIGINT,
@@ -57,27 +91,99 @@ const MyTischtennis = sequelize.define('MyTischtennis', {
},
cookie: {
type: DataTypes.TEXT,
allowNull: true
allowNull: true,
set(value) {
if (value === null || value === undefined) {
this.setDataValue('cookie', null);
} else {
const encryptedValue = encryptData(value);
this.setDataValue('cookie', encryptedValue);
}
},
get() {
const encryptedValue = this.getDataValue('cookie');
if (!encryptedValue) return null;
return decryptData(encryptedValue);
}
},
userData: {
type: DataTypes.JSON,
type: DataTypes.TEXT, // Changed from JSON to TEXT to store encrypted JSON string
allowNull: true,
field: 'user_data'
field: 'user_data',
set(value) {
if (value === null || value === undefined) {
this.setDataValue('userData', null);
} else {
const jsonString = typeof value === 'string' ? value : JSON.stringify(value);
const encryptedValue = encryptData(jsonString);
this.setDataValue('userData', encryptedValue);
}
},
get() {
const encryptedValue = this.getDataValue('userData');
if (!encryptedValue) return null;
try {
const decryptedString = decryptData(encryptedValue);
return JSON.parse(decryptedString);
} catch (error) {
console.error('Error decrypting/parsing userData:', error);
return null;
}
}
},
clubId: {
type: DataTypes.STRING,
allowNull: true,
field: 'club_id'
field: 'club_id',
set(value) {
if (value === null || value === undefined) {
this.setDataValue('clubId', null);
} else {
const encryptedValue = encryptData(value);
this.setDataValue('clubId', encryptedValue);
}
},
get() {
const encryptedValue = this.getDataValue('clubId');
if (!encryptedValue) return null;
return decryptData(encryptedValue);
}
},
clubName: {
type: DataTypes.STRING,
allowNull: true,
field: 'club_name'
field: 'club_name',
set(value) {
if (value === null || value === undefined) {
this.setDataValue('clubName', null);
} else {
const encryptedValue = encryptData(value);
this.setDataValue('clubName', encryptedValue);
}
},
get() {
const encryptedValue = this.getDataValue('clubName');
if (!encryptedValue) return null;
return decryptData(encryptedValue);
}
},
fedNickname: {
type: DataTypes.STRING,
allowNull: true,
field: 'fed_nickname'
field: 'fed_nickname',
set(value) {
if (value === null || value === undefined) {
this.setDataValue('fedNickname', null);
} else {
const encryptedValue = encryptData(value);
this.setDataValue('fedNickname', encryptedValue);
}
},
get() {
const encryptedValue = this.getDataValue('fedNickname');
if (!encryptedValue) return null;
return decryptData(encryptedValue);
}
},
lastLoginAttempt: {
type: DataTypes.DATE,