Dr-Swopt 1 month ago
parent
commit
fb79f97f7a
4 changed files with 40 additions and 20 deletions
  1. 1 0
      src/auth/auth.controller.ts
  2. 12 6
      src/auth/webauthn.service.ts
  3. 3 3
      src/config/config.ts
  4. 24 11
      src/main.ts

+ 1 - 0
src/auth/auth.controller.ts

@@ -41,6 +41,7 @@ export class AuthController {
     ) {
         this.logger.log(`Registering ${body.name}`)
         const expectedChallenge = session.challenge;
+        console.log(expectedChallenge)
         if (!expectedChallenge) {
             throw new BadRequestException('Missing challenge in session');
         }

+ 12 - 6
src/auth/webauthn.service.ts

@@ -60,14 +60,20 @@ export class WebauthnService {
         this.logger.log('Verifying registration response...');
         this.logger.debug(JSON.stringify(responseBody, null, 2));
 
-        return verifyRegistrationResponse({
-            response: responseBody,
-            expectedChallenge,
-            expectedOrigin: this.origin,
-            expectedRPID: this.rpID,
-        });
+        try {
+            return verifyRegistrationResponse({
+                response: responseBody,
+                expectedChallenge,
+                expectedOrigin: this.origin,  // <-- must exactly match browser origin
+                expectedRPID: this.rpID,
+            });
+        } catch (err) {
+            this.logger.error('WebAuthn verification failed:', err);
+            throw err; // propagate so controller still returns 400
+        }
     }
 
+
     async generateAuthenticationOptions(registeredDevices?: {
         credentialID: Uint8Array;
         transports?: AuthenticatorTransport[];

+ 3 - 3
src/config/config.ts

@@ -1,7 +1,7 @@
 
 export const serverConfig = {
-  exposedUrl: 'https://192.168.100.100:4000',
+  exposedUrl: 'https://localhost:4000',
   rpName: 'My App',
-  rpId: '192.168.100.100',
-  origin: 'https://192.168.100.100:4000',
+  rpId: 'localhost',
+  origin: 'http://localhost:4200',
 };

+ 24 - 11
src/main.ts

@@ -10,15 +10,16 @@ import { ValidationPipe } from '@nestjs/common';
 async function bootstrap() {
   const certsDir = join(__dirname, '..', 'certs');
   const httpsOptions = {
-    key: fs.readFileSync(join(certsDir, '192.168.100.100+2-key.pem')),
-    cert: fs.readFileSync(join(certsDir, '192.168.100.100+2.pem')),
+    key: fs.readFileSync(join(certsDir, 'local-key.pem')),
+    cert: fs.readFileSync(join(certsDir, 'local-cert.pem')),
   };
 
   // const app = await NestFactory.create<NestExpressApplication>(AppModule);
-  const app = await NestFactory.create<NestExpressApplication>(AppModule, {
-    httpsOptions, // <-- Let Nest bind HTTPS
-  });
+  // const app = await NestFactory.create<NestExpressApplication>(AppModule, {
+  //   httpsOptions, // <-- Let Nest bind HTTPS
+  // });
 
+  const app = await NestFactory.create<NestExpressApplication>(AppModule);
   app.useGlobalPipes(
     new ValidationPipe({
       whitelist: true, // strips extra fields
@@ -27,7 +28,10 @@ async function bootstrap() {
     }),
   );
 
-  app.enableCors();
+  app.enableCors({
+    origin: 'http://localhost:4200', // your Angular app URL
+    credentials: true,
+  });
   app.setGlobalPrefix('api');
 
   const angularDistPath = join(__dirname, '..', '..', 'web-app', 'dist', 'mobile-auth-web-app', 'browser');
@@ -37,11 +41,20 @@ async function bootstrap() {
   app.setBaseViewsDir(angularDistPath);
   app.setViewEngine('html');
 
-  app.use(session({
-    secret: 'your-secret',
-    resave: false,
-    saveUninitialized: false,
-  }));
+  app.use(
+    session({
+      secret: 'your-secret',
+      resave: false,
+      saveUninitialized: false,
+      cookie: {
+        httpOnly: true,           // browser can’t access cookie via JS
+        secure: false,            // set true if using HTTPS
+        sameSite: 'lax',          // allow sending cookies cross-origin on localhost
+        maxAge: 24 * 60 * 60 * 1000, // 1 day
+      },
+    }),
+  );
+
 
   app.use((req, res, next) => {
     const isStaticAsset = req.url.includes('.');