From 24e7bfee18a26231b10096fcd37398a494b6ade4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bodor=20M=C3=A1t=C3=A9?= <bmate711@gmail.com>
Date: Fri, 1 May 2020 17:19:55 +0200
Subject: [PATCH] Create refresToken middleware

---
 src/index.ts                          |  5 ++-
 src/middlewares/auth/authenticated.ts | 22 +++++-----
 src/middlewares/auth/complete.ts      | 60 ++++++++++++++-------------
 src/middlewares/auth/login.ts         | 24 +++++------
 src/middlewares/auth/logout.ts        | 14 +++----
 src/middlewares/auth/refreshToken.ts  | 18 ++++++++
 src/models/.gitkeep                   |  0
 src/models/user.interface.ts          |  8 ++++
 src/routes/auth.ts                    |  6 +--
 src/utils/.gitkeep                    |  0
 src/utils/declarations/session.d.ts   | 10 +++++
 tsconfig.json                         |  4 ++
 12 files changed, 108 insertions(+), 63 deletions(-)
 create mode 100644 src/middlewares/auth/refreshToken.ts
 delete mode 100644 src/models/.gitkeep
 create mode 100644 src/models/user.interface.ts
 delete mode 100644 src/utils/.gitkeep
 create mode 100644 src/utils/declarations/session.d.ts

diff --git a/src/index.ts b/src/index.ts
index e880caa5..f26f67e4 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -3,13 +3,14 @@ import express, { Request, Response, NextFunction, Application } from "express";
 import bodyParser from "body-parser";
 import expressSession from "express-session";
 import authRoute from './routes/auth';
+import userRoute from './routes/user';
 
 const app: Application = express();
 
 app.use(bodyParser.json()); // for parsing application/json
 app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
 app.use(expressSession({
-  secret: process.env.SESSION_SECRET || "alma",
+  secret: process.env.SESSION_SECRET || "secret",
   resave: false,
   saveUninitialized: true,
   cookie: { secure: false }
@@ -18,7 +19,7 @@ app.use(expressSession({
 app.get("/", (req: Request, res: Response) => {
   let message = "World!";
   if(req.session!.user)
-     message = req.session!.user!.sn || "World!";
+     message = req.session!.user!.name || "World!";
   res.send( "Hello " + message)
 });
 
diff --git a/src/middlewares/auth/authenticated.ts b/src/middlewares/auth/authenticated.ts
index d5f7ea0e..139a50d9 100644
--- a/src/middlewares/auth/authenticated.ts
+++ b/src/middlewares/auth/authenticated.ts
@@ -1,12 +1,12 @@
-import {Request, Response, NextFunction} from "express";
-
-const authenticated = () => (req : Request, res : Response, next: NextFunction ) =>{
-    if(req.session!.user)
-        next();
-    else{
-        res.status(403);
-        res.json({message: "You have to login to see this page"});
-    }
-}
-
+import {Request, Response, NextFunction} from "express";
+
+const authenticated = () => (req : Request, res : Response, next: NextFunction ) =>{
+    if(req.session!.user)
+        next();
+    else{
+        res.status(403);
+        res.json({message: "You have to login to see this page"});
+    }
+}
+
 export default authenticated;
\ No newline at end of file
diff --git a/src/middlewares/auth/complete.ts b/src/middlewares/auth/complete.ts
index dedc5c8c..2f51c837 100644
--- a/src/middlewares/auth/complete.ts
+++ b/src/middlewares/auth/complete.ts
@@ -1,29 +1,33 @@
-import { Request, Response } from 'express';
-import {oauth2, scope} from '../../utils/auth'
-import axios from "axios";
-
-
-const complete = () => async (req: Request, res: Response) => { 
-    const tokenConfig = {
-        code: req.query.code,
-        scope: scope,
-        redirect_uri: ""
-    };
-    
-    try {
-        const result = await oauth2().authorizationCode.getToken(tokenConfig);
-        const token = oauth2().accessToken.create(result);
-        await axios.get(`https://auth.sch.bme.hu/api/profile/?access_token=${token.token.access_token}`)
-            .then( (response) =>  {
-                req.session!.user = response.data;
-             })
-            .catch(function (error) {
-                console.log(error);
-            });
-        res.redirect('/');
-    } catch (error) {
-        console.log('Access Token Error', error.message);   
-    }
-};
-
+import { Request, Response } from 'express';
+import {oauth2, scope} from '../../utils/auth'
+import axios from "axios";
+
+
+const complete = () => async (req: Request, res: Response) => { 
+    const tokenConfig = {
+        code: req.query.code,
+        scope: scope,
+        redirect_uri: ""
+    };
+    
+    try {
+        const token = await oauth2().authorizationCode.getToken(tokenConfig);
+        await axios.get(`https://auth.sch.bme.hu/api/profile/?access_token=${token.access_token}`)
+            .then( (response) =>  {
+                req.session!.user = {
+                    id: String(response.data.basic),
+                    email: String(response.data.mail),
+                    name: `${response.data.sn} ${response.data.givenName}` ,
+                    token,
+                };
+             })
+            .catch(function (error) {
+                console.log(error);
+            });
+        res.redirect('/');
+    } catch (error) {
+        console.log('Access Token Error', error.message);   
+    }
+};
+
 export default complete;
\ No newline at end of file
diff --git a/src/middlewares/auth/login.ts b/src/middlewares/auth/login.ts
index 356629f1..a1efd4d7 100644
--- a/src/middlewares/auth/login.ts
+++ b/src/middlewares/auth/login.ts
@@ -1,13 +1,13 @@
-import { Request, Response } from 'express';
-import {oauth2, scope} from '../../utils/auth'
-
-
-const authorizationUri = oauth2().authorizationCode.authorizeURL({
-    scope: scope,
-});
-
-
-const login = () =>   (req: Request, res: Response) => res.redirect(authorizationUri);
-
-
+import { Request, Response } from 'express';
+import {oauth2, scope} from '../../utils/auth'
+
+
+const authorizationUri = oauth2().authorizationCode.authorizeURL({
+    scope: scope,
+});
+
+
+const login = () =>   (req: Request, res: Response) => res.redirect(authorizationUri);
+
+
 export default login;
\ No newline at end of file
diff --git a/src/middlewares/auth/logout.ts b/src/middlewares/auth/logout.ts
index 791772f7..9367d85f 100644
--- a/src/middlewares/auth/logout.ts
+++ b/src/middlewares/auth/logout.ts
@@ -1,8 +1,8 @@
-import { Request, Response } from 'express';
-
-const logout = () => (req : Request, res : Response) =>{
-    req.session!.destroy(() => console.log("user logged out."));
-    res.redirect("/");
-}
-
+import { Request, Response } from 'express';
+
+const logout = () => (req : Request, res : Response) =>{
+    req.session!.destroy(() => console.log("user logged out."));
+    res.redirect("/");
+}
+
 export default logout;
\ No newline at end of file
diff --git a/src/middlewares/auth/refreshToken.ts b/src/middlewares/auth/refreshToken.ts
new file mode 100644
index 00000000..1d857bb1
--- /dev/null
+++ b/src/middlewares/auth/refreshToken.ts
@@ -0,0 +1,18 @@
+import { Request, Response, NextFunction } from 'express';
+import { oauth2 } from '../../utils/auth'
+
+const refreshToken = () => async (req: Request, res: Response, next: NextFunction) => {
+  if (req.session && req.session.user) {
+    try{
+      let accessToken = oauth2().accessToken.create(req.session.user.token);
+      if (accessToken.expired(Number(process.env.AUTH_TOKEN_EXPIRATION_WINDOW_IN_SECONDS))) {
+          req.session.user.token = await accessToken.refresh().then(accessToken => accessToken.token);
+        } 
+      }catch (error) {
+        console.log('Error refreshing access token: ', error.message);
+    }
+  }
+  next();
+}
+
+export default refreshToken;
\ No newline at end of file
diff --git a/src/models/.gitkeep b/src/models/.gitkeep
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/models/user.interface.ts b/src/models/user.interface.ts
new file mode 100644
index 00000000..50df6043
--- /dev/null
+++ b/src/models/user.interface.ts
@@ -0,0 +1,8 @@
+import { Token } from "simple-oauth2";
+
+export interface User{
+    email: string,
+    name: string,
+    id: string,
+    token: Token,
+}
\ No newline at end of file
diff --git a/src/routes/auth.ts b/src/routes/auth.ts
index b930250f..a11e4dcb 100644
--- a/src/routes/auth.ts
+++ b/src/routes/auth.ts
@@ -2,9 +2,9 @@ import { Application } from 'express';
 import login from '../middlewares/auth/login';
 import complete from '../middlewares/auth/complete';
 import logout from '../middlewares/auth/logout';
-import authenticated from '../middlewares/auth/authenticated'
+import authenticated from '../middlewares/auth/authenticated';
 
- const authRout = (app: Application): void => {
+ const authRoute = (app: Application): void => {
     app.get('/login', login() );
 
     app.get('/complete', complete() );
@@ -12,4 +12,4 @@ import authenticated from '../middlewares/auth/authenticated'
     app.get('/logout', authenticated(), logout() );
 }
 
-export default authRout;
\ No newline at end of file
+export default authRoute;
\ No newline at end of file
diff --git a/src/utils/.gitkeep b/src/utils/.gitkeep
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/utils/declarations/session.d.ts b/src/utils/declarations/session.d.ts
new file mode 100644
index 00000000..70023005
--- /dev/null
+++ b/src/utils/declarations/session.d.ts
@@ -0,0 +1,10 @@
+import { AccessToken } from "simple-oauth2";
+import { User } from 'src/models/user.interface';
+
+declare global {
+    namespace Express {
+        export interface Session {
+            user: User | null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index f745dd84..fe197975 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,4 +1,8 @@
 {
+  "files": [
+    "./src/utils/declarations/session.d.ts"
+  ],
+
   "compilerOptions": {
     "module": "commonjs",
     "strict": true,
-- 
GitLab