From 7bb7204ceadb4fc5d78ad2056d233c39edb6f594 Mon Sep 17 00:00:00 2001 From: rodrigo goncalves Date: Tue, 31 Jan 2023 14:38:39 -0300 Subject: [PATCH] refactor: refresh token --- .DS_Store | Bin 0 -> 6148 bytes package-lock.json | 16 ++++++++++++- package.json | 5 ++-- src/.DS_Store | Bin 0 -> 6148 bytes src/controllers/SessionsController.js | 6 ++--- src/controllers/UserRefreshToken.js | 22 +++++++++--------- src/database/.DS_Store | Bin 0 -> 6148 bytes src/database/database.db | Bin 32768 -> 32768 bytes .../20220823161207_createUsersToken.js | 6 ++--- src/middlewares/ensureAuthenticated.js | 1 - src/providers/GenerateRefreshToken.js | 16 +++++++++---- 11 files changed, 45 insertions(+), 27 deletions(-) create mode 100644 .DS_Store create mode 100644 src/.DS_Store create mode 100644 src/database/.DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..abed0c510b32e6f2268532e4edb53d97ff29fb77 GIT binary patch literal 6148 zcmeHKF=_)r43uIQ4ryGb+%Mz@i*a6%4}|z!1Pq28fs|L}U4B|-Bo#52GzK?j1lrlv zYIfNvPA4<-&FAoBwl=dBoM_)1=Ei;c%5@r#$lXg{~aLr9*i&ehyCL3 z4sXZffuseF#MUro2sg>3fE17dQa}nwfr}NWO1gTu_yiH9fE2h@1^9hvaAGf<664c> zAzA?765%k+qn7|S27tYAN<;+aNd+d=tHto7Bi<^n7fy*uH;Hp73T1f#Za8nBSa{IE~;7L_mXOCm8ZSYq(b53v?=0U*_ lu;$4JV&#yR$T;glG3#Dfmh&j59iNr7uC@B>R^8bSa7 literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json index fda352b..134bfdd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,8 @@ "knex": "^2.2.0", "multer": "^1.4.5-lts.1", "sqlite3": "^5.0.11", - "swagger-ui-express": "^4.5.0" + "swagger-ui-express": "^4.5.0", + "uuid": "^9.0.0" }, "devDependencies": { "nodemon": "^2.0.19" @@ -2534,6 +2535,14 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -4509,6 +4518,11 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, + "uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/package.json b/package.json index f393711..3a07854 100644 --- a/package.json +++ b/package.json @@ -21,9 +21,10 @@ "knex": "^2.2.0", "multer": "^1.4.5-lts.1", "sqlite3": "^5.0.11", - "swagger-ui-express": "^4.5.0" + "swagger-ui-express": "^4.5.0", + "uuid": "^9.0.0" }, "devDependencies": { "nodemon": "^2.0.19" } -} \ No newline at end of file +} diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..d625f4218d4b4326c85377b8eb06804066d74b3a GIT binary patch literal 6148 zcmeHKISv9b477n_C7LZM^96noA$S2F;8;2&3ZUPLckwjFM*&*sph08FnZ)rV$`tFh zi0Ia;(5S$#6?g!7oE2XH literal 0 HcmV?d00001 diff --git a/src/controllers/SessionsController.js b/src/controllers/SessionsController.js index 9cc6552..72fd597 100644 --- a/src/controllers/SessionsController.js +++ b/src/controllers/SessionsController.js @@ -23,14 +23,12 @@ class SessionsController { const generateTokenProvider = new GenerateToken(); const token = await generateTokenProvider.execute(user.id); - await knex("users_tokens").where({ user_id: user.id }).delete(); - const generateRefreshToken = new GenerateRefreshToken(); - generateRefreshToken.execute(user.id, token); + const refresh_token = await generateRefreshToken.execute(user.id); delete user.password; - response.status(201).json({ token, user }); + response.status(201).json({ user, token, refresh_token }); } } diff --git a/src/controllers/UserRefreshToken.js b/src/controllers/UserRefreshToken.js index d2b92df..4799f64 100644 --- a/src/controllers/UserRefreshToken.js +++ b/src/controllers/UserRefreshToken.js @@ -6,33 +6,33 @@ const dayjs = require("dayjs"); class UserRefreshToken { async create(request, response) { - const { token } = request.body; + const { refresh_token } = request.body; - if (!token) { + if (!refresh_token) { throw new AppError("Informe o token de autenticação.", 401); } - const userToken = await knex("users_tokens").where({ token }).first(); + const refreshToken = await knex("refresh_token").where({ refresh_token }).first(); - if (!userToken) { - throw new AppError("Refresh token não encontrado para este usuário.", 404); + if (!refreshToken) { + throw new AppError("Refresh token não encontrado para este usuário.", 401); } const generateTokenProvider = new GenerateToken(); - const refreshToken = await generateTokenProvider.execute(userToken.user_id); + const token = await generateTokenProvider.execute(refreshToken.user_id); - const refreshTokenExpired = dayjs().isAfter(dayjs.unix(userToken.expires_in)); + const refreshTokenExpired = dayjs().isAfter(dayjs.unix(refreshToken.expires_in)); if (refreshTokenExpired) { - await knex("users_tokens").where({ user_id: userToken.user_id }).delete(); + await knex("refresh_token").where({ user_id: refreshToken.user_id }).delete(); const generateRefreshToken = new GenerateRefreshToken(); - await generateRefreshToken.execute(userToken.user_id, refreshToken); + const newRefreshToken = await generateRefreshToken.execute(refreshToken.user_id, refresh_token); - return response.json({ token: refreshToken }); + return response.json({ token, refresh_token: newRefreshToken }); } - return response.json({ token }); + return response.json({ token, refresh_token }); } } diff --git a/src/database/.DS_Store b/src/database/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0M!Yvt9!EbhrGcLAWf0)FO3 zX2!|2{uVEN=mc}~)HEa0v=m(<6Y~^Z6C(>VUCZP|3*8jMv=o!nM581_GXu1O#KOwR001(h BW)%Pc literal 32768 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 v`D!p-4k-EU7(|y1rq?!O39h_V-8 knex.schema.createTable("users_tokens", table => { +exports.up = knex => knex.schema.createTable("refresh_token", table => { table.increments("id"); table.integer("expires_in") + table.text("refresh_token") table.integer("user_id").references("id").inTable("users"); - table.text("token").notNullable(); table.timestamp("created_at").default(knex.fn.now()); }); -exports.down = knex => knex.schema.dropTable("users_tokens"); \ No newline at end of file +exports.down = knex => knex.schema.dropTable("users_tokens"); diff --git a/src/middlewares/ensureAuthenticated.js b/src/middlewares/ensureAuthenticated.js index add7a0a..7185fab 100644 --- a/src/middlewares/ensureAuthenticated.js +++ b/src/middlewares/ensureAuthenticated.js @@ -9,7 +9,6 @@ async function ensureAuthenticated(request, response, next) { throw new AppError("JWT token não informado", 401); } - const [, token] = authHeader.split(" "); try { diff --git a/src/providers/GenerateRefreshToken.js b/src/providers/GenerateRefreshToken.js index 8cbaba3..850b148 100644 --- a/src/providers/GenerateRefreshToken.js +++ b/src/providers/GenerateRefreshToken.js @@ -1,15 +1,21 @@ const knex = require("../database"); const dayjs = require("dayjs"); +const uuid = require('uuid') class GenerateRefreshToken { - async execute(userId, newToken) { - const expires_in = dayjs().add(15, "second").unix(); + async execute(user_id) { + await knex("refresh_token").where({ user_id }).delete(); - await knex("users_tokens").insert({ - user_id: userId, + const expires_in = dayjs().add(15, "m").unix(); + const refresh_token = uuid.v4(); + + await knex("refresh_token").insert({ + user_id, expires_in, - token: newToken + refresh_token }); + + return refresh_token; } }