diff --git a/idp/.env.skeleton b/idp/.env.skeleton
index fc54d64..4768b0b 100644
--- a/idp/.env.skeleton
+++ b/idp/.env.skeleton
@@ -11,5 +11,6 @@ IGNORE_PASSWORDS=FALSE # hier kann man sich nur mit dem Username einloggen, nich
JWT_SECRET=super-geheimes-secret
JWT_EXPIRES_IN=10m
JWT_REFRESH_EXPIRES_IN=1w
+SESSION_SECRET=MYSESSIONSECRET2024
APPLICATIONPORT=5000
\ No newline at end of file
diff --git a/idp/package-lock.json b/idp/package-lock.json
index 1a45654..148b650 100644
--- a/idp/package-lock.json
+++ b/idp/package-lock.json
@@ -21,6 +21,7 @@
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"dotenv": "^16.4.5",
+ "express-session": "^1.18.0",
"mysql2": "^3.11.0",
"nestjs-form-data": "^1.9.91",
"passport": "^0.7.0",
@@ -36,6 +37,7 @@
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@types/express": "^4.17.17",
+ "@types/express-session": "^1.18.0",
"@types/jest": "^29.5.2",
"@types/node": "^20.3.1",
"@types/supertest": "^6.0.0",
@@ -2206,6 +2208,15 @@
"@types/send": "*"
}
},
+ "node_modules/@types/express-session": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.18.0.tgz",
+ "integrity": "sha512-27JdDRgor6PoYlURY+Y5kCakqp5ulC0kmf7y+QwaY+hv9jEFuQOThgkjyA53RP3jmKuBsH5GR6qEfFmvb8mwOA==",
+ "dev": true,
+ "dependencies": {
+ "@types/express": "*"
+ }
+ },
"node_modules/@types/graceful-fs": {
"version": "4.1.9",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
@@ -4652,6 +4663,42 @@
"node": ">= 0.10.0"
}
},
+ "node_modules/express-session": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.0.tgz",
+ "integrity": "sha512-m93QLWr0ju+rOwApSsyso838LQwgfs44QtOP/WBiwtAgPIo/SAh1a5c6nn2BR6mFNZehTpqKDESzP+fRHVbxwQ==",
+ "dependencies": {
+ "cookie": "0.6.0",
+ "cookie-signature": "1.0.7",
+ "debug": "2.6.9",
+ "depd": "~2.0.0",
+ "on-headers": "~1.0.2",
+ "parseurl": "~1.3.3",
+ "safe-buffer": "5.2.1",
+ "uid-safe": "~2.1.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/express-session/node_modules/cookie-signature": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz",
+ "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA=="
+ },
+ "node_modules/express-session/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/express-session/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
"node_modules/express/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -7293,6 +7340,14 @@
"node": ">= 0.8"
}
},
+ "node_modules/on-headers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
+ "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -7843,6 +7898,14 @@
}
]
},
+ "node_modules/random-bytes": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
+ "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -9405,6 +9468,17 @@
"node": ">=8"
}
},
+ "node_modules/uid-safe": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
+ "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
+ "dependencies": {
+ "random-bytes": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/undici-types": {
"version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
diff --git a/idp/package.json b/idp/package.json
index c14d054..04fa6df 100644
--- a/idp/package.json
+++ b/idp/package.json
@@ -32,6 +32,7 @@
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"dotenv": "^16.4.5",
+ "express-session": "^1.18.0",
"mysql2": "^3.11.0",
"nestjs-form-data": "^1.9.91",
"passport": "^0.7.0",
@@ -47,6 +48,7 @@
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@types/express": "^4.17.17",
+ "@types/express-session": "^1.18.0",
"@types/jest": "^29.5.2",
"@types/node": "^20.3.1",
"@types/supertest": "^6.0.0",
diff --git a/idp/src/app.module.ts b/idp/src/app.module.ts
index 3246054..9210011 100644
--- a/idp/src/app.module.ts
+++ b/idp/src/app.module.ts
@@ -1,4 +1,4 @@
-import { Module } from '@nestjs/common';
+import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { AppService } from './app.service';
import { AuthModule } from './auth/auth.module';
import { TypeOrmModule } from '@nestjs/typeorm';
@@ -6,9 +6,12 @@ import { ConfigModule } from '@nestjs/config';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
import { LoggerModule } from './core/logger.module';
+import { SessionMiddleware } from './core/session.middleware';
+import { ClientModule } from './client/client.module';
@Module({
imports: [
AuthModule,
+ ClientModule,
ConfigModule.forRoot({
envFilePath: ['.env'],
isGlobal: true,
@@ -47,4 +50,8 @@ import { LoggerModule } from './core/logger.module';
providers: [AppService],
exports: [],
})
-export class AppModule {}
+export class AppModule implements NestModule {
+ configure(consumer: MiddlewareConsumer) {
+ consumer.apply(SessionMiddleware).forRoutes('*');
+ }
+}
diff --git a/idp/src/auth/auth.controller.ts b/idp/src/auth/auth.controller.ts
index 0fd90e3..3087f55 100644
--- a/idp/src/auth/auth.controller.ts
+++ b/idp/src/auth/auth.controller.ts
@@ -1,4 +1,4 @@
-import { Body, Controller, Get, Post, Query } from '@nestjs/common';
+import { Body, Controller, Get, Post, Query, Req } from '@nestjs/common';
import { UsersService } from 'src/users/users.service';
import { ClientService } from 'src/client/client.service';
import { FormDataRequest } from 'nestjs-form-data';
@@ -37,9 +37,11 @@ export class AuthController {
@Post('login-with-session-id')
async loginWithCode(
+ @Req() request: Request,
@Body('code') code: string,
@Body('client_id') clientId: string,
) {
+ console.log(request['session']);
return this.usersService.loginWithSessionKey(code, clientId);
}
diff --git a/idp/src/core/session.middleware.ts b/idp/src/core/session.middleware.ts
new file mode 100644
index 0000000..c6aa276
--- /dev/null
+++ b/idp/src/core/session.middleware.ts
@@ -0,0 +1,13 @@
+import { Injectable, NestMiddleware } from '@nestjs/common';
+import { Request, Response, NextFunction } from 'express';
+
+@Injectable()
+export class SessionMiddleware implements NestMiddleware {
+ use(req: Request, res: Response, next: NextFunction) {
+ const request = req as any;
+ request.session.visits = request.session.visits
+ ? request.session.visits + 1
+ : 1;
+ next();
+ }
+}
diff --git a/idp/src/main.ts b/idp/src/main.ts
index d3cabef..8908a46 100644
--- a/idp/src/main.ts
+++ b/idp/src/main.ts
@@ -2,6 +2,7 @@ import { NestFactory, Reflector } from '@nestjs/core';
import { AppModule } from './app.module';
import { Logger, ValidationPipe } from '@nestjs/common';
import { ClassSerializerInterceptor } from '@nestjs/common';
+import * as session from 'express-session';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
@@ -12,6 +13,14 @@ async function bootstrap() {
app.enableCors();
+ app.use(
+ session({
+ secret: process.env.SESSION_SECRET,
+ resave: false,
+ saveUninitialized: false,
+ }),
+ );
+
app.useGlobalPipes(
new ValidationPipe({
transform: true, // Transform is recomended configuration for avoind issues with arrays of files transformations
diff --git a/idp/src/users/users.service.ts b/idp/src/users/users.service.ts
index ff63a9d..4d01ca0 100644
--- a/idp/src/users/users.service.ts
+++ b/idp/src/users/users.service.ts
@@ -48,7 +48,7 @@ export class UsersService {
username: string,
password: string,
clientId: string,
- ): Promise<{ code: string; session_key: string }> {
+ ): Promise<{ code: string; session_key: string; access?: string }> {
const user = await this.userRepo.findByUsername(username);
if (!user) {
this.logger.error(`User ${username} not found`);
@@ -74,7 +74,9 @@ export class UsersService {
});
const session = await this.sessionRepo.save(s);
- return { code: token.code, session_key: session.id };
+ const refresh = this.createAccessToken(user);
+
+ return { code: token.code, session_key: session.id, access: refresh };
}
async createAuthToken(user: User, client: Client) {
@@ -111,7 +113,9 @@ export class UsersService {
throw new HttpException('User is not active', 401);
}
- const token = this.createAuthToken(user, client);
+ const token = await this.createAuthToken(user, client);
+ const refresh = this.createAccessToken(user);
+ token.user['access'] = refresh;
this.logger.log(`User logged in with code on client ${clientId}`);
return token;
}
@@ -182,7 +186,7 @@ export class UsersService {
}
private createRefreshToken(user: User) {
- this.jwtService.sign(
+ return this.jwtService.sign(
{
type: 'refresh',
id: user.id,
diff --git a/idp_client/src/app/app.component.html b/idp_client/src/app/app.component.html
index 955af37..90c6b64 100644
--- a/idp_client/src/app/app.component.html
+++ b/idp_client/src/app/app.component.html
@@ -1,2 +1 @@
-
-iodsuj
\ No newline at end of file
+
\ No newline at end of file
diff --git a/idp_client/src/app/app.routes.ts b/idp_client/src/app/app.routes.ts
index 84377bd..5f7aa2b 100644
--- a/idp_client/src/app/app.routes.ts
+++ b/idp_client/src/app/app.routes.ts
@@ -1,9 +1,11 @@
import { Routes } from '@angular/router';
import { LoginComponent } from './auth/login/login.component';
import { RegisterComponent } from './auth/register/register.component';
+import { DashboardComponent } from './dashboard/dashboard.component';
export const routes: Routes = [
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
+ { path: 'dashboard', component: DashboardComponent },
{ path: '', component: LoginComponent },
];
diff --git a/idp_client/src/app/auth/login/login.component.html b/idp_client/src/app/auth/login/login.component.html
index bc30657..0fd9c27 100644
--- a/idp_client/src/app/auth/login/login.component.html
+++ b/idp_client/src/app/auth/login/login.component.html
@@ -11,7 +11,7 @@
-