-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* SK-217 Implemented group chat images (#117) * SK-189 added `avatar_object` field for user object * SK-189 implemented the logic of creating links for downloading user avatars * SK-189 renamed downloadFile to getFileDownloadUrl * SK-217 added `image_object` for Conversation fields * SK-217 added `image_url` field to the system event * SK-217 added sending update request to other users * SK-217 cleanup * SK-217 minor fix * SK-217 added image_object for conversationCreate * SK-217 add log * SK-217 remove log * SK-217 add log * SK-217 remove log * SK-194 updated `typing` object (#121) * Sk-194 updated typing object * SK-194 updated API.md * SK-234 removed file name from uuid in file `object_id` (#122) * updated CHANGELOG.md (0.24.0 -> 0.25.0) * Updated tests for status typing (removed tests for deleted fields) * FM-27 added device_token for push subscription (#136) * Release 0.25.0 (#123) * SK-217 Implemented group chat images (#117) * SK-189 added `avatar_object` field for user object * SK-189 implemented the logic of creating links for downloading user avatars * SK-189 renamed downloadFile to getFileDownloadUrl * SK-217 added `image_object` for Conversation fields * SK-217 added `image_url` field to the system event * SK-217 added sending update request to other users * SK-217 cleanup * SK-217 minor fix * SK-217 added image_object for conversationCreate * SK-217 add log * SK-217 remove log * SK-217 add log * SK-217 remove log * SK-194 updated `typing` object (#121) * Sk-194 updated typing object * SK-194 updated API.md * SK-234 removed file name from uuid in file `object_id` (#122) * updated CHANGELOG.md (0.24.0 -> 0.25.0) * Release 0.25.0 (#124) * SK-217 Implemented group chat images (#117) * SK-189 added `avatar_object` field for user object * SK-189 implemented the logic of creating links for downloading user avatars * SK-189 renamed downloadFile to getFileDownloadUrl * SK-217 added `image_object` for Conversation fields * SK-217 added `image_url` field to the system event * SK-217 added sending update request to other users * SK-217 cleanup * SK-217 minor fix * SK-217 added image_object for conversationCreate * SK-217 add log * SK-217 remove log * SK-217 add log * SK-217 remove log * SK-194 updated `typing` object (#121) * Sk-194 updated typing object * SK-194 updated API.md * SK-234 removed file name from uuid in file `object_id` (#122) * updated CHANGELOG.md (0.24.0 -> 0.25.0) * Updated tests for status typing (removed tests for deleted fields) * Update API.md * Update README.md * Update README.md * Update README.md * Update README.md * updated package.json * Update README.md * Сhange development flow (#132) * FM-27 added `device_token` for push subscription * FM-27 minor cleanup * FM-27 removed `rsmq-promise`, updated bull queue methods * FM-27 renamed minor comments --------- Co-authored-by: IgorKhomenko <[email protected]> Co-authored-by: Igor Khomenko <[email protected]> Co-authored-by: ku9nov <[email protected]> * updated CHANGELOG.md * renamed env file * updated tests for `push_subcriptions`, added indexes for the `push_subcriptions` collection * SK-273 remove `platform` field from pushEvent object (#141) * SK-272 extended `conversation_list` request to allow request convs by ids (#142) * SK-272 added `ids` options for conversation_list, added test, updated API.md * SK-272 added limit for ids field - 10 * SK-272 updated API.md * Updated CHANGELOG.md * Fixes different naming of methods * Updated CHANGELOG.md * Added `cid` field for push notification object * SK-278 implemented support for `refresh_token`, added `connect_socket` request (#147) * SK-278 added `connect_socket` request, implemented support for `refresh_token` * SK-278 updated API.md * SK-278 init HttpAuthController * SK-278 minor fix * SK-278 deprecated user_logout * SK-278 added log * SK-278 tmpToken -> refresh_token * SK-278 added cookie signature * SK-278 minor fix * SK-278 removed log * SK-278 remove token from cookie if it`ss incorrect * SK-278 added function of reading header * SK-278 removed error validation from getAccessTokenFromHeader * SK-278 added logs * SK-278 removed logs * SK-278 updated API.md * SK-278 fixed expired_at field in auth response * SK-278 fixed access and refresh jwt expiresIn * SK-278 added refresh_token to all variants of response for auth * SK-278 create new refresh token every time * SK-278 added log * SK-278 replaced cors settings * SK-278 added onAborted handler for http requests * Updated `user_search` query param, changed status for `unauthorized` error (#146) * Updated user_search param name & updated error status for `Unauthorized` * added logs * removed logs * Added a load testing scheme (#149) * added load test * updated test plan * updated README.md * added new envs * updated pm2.config.cjs * added testing results * updated RESULTS.md * updated RESULTS.md * updated CHANGELOG.md * revert pm2.config.cjs * undo revert pm2.config.cjs * fix tests --------- Co-authored-by: IgorKhomenko <[email protected]> Co-authored-by: Igor Khomenko <[email protected]> Co-authored-by: ku9nov <[email protected]> Co-authored-by: ku9nov <[email protected]>
- Loading branch information
1 parent
3562fb3
commit 8c0aaa8
Showing
34 changed files
with
1,014 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
import BaseHttpController from "./base.js" | ||
|
||
import signature from "cookie-signature" | ||
|
||
import extractRefreshTokenFromCookie from "../../../JSON/utils/extract_refresh_token_from_cookie.js" | ||
import { ERROR_STATUES } from "../../../../app/constants/errors.js" | ||
|
||
import ServiceLocatorContainer from "@sama/common/ServiceLocatorContainer.js" | ||
|
||
class HttpAuthController extends BaseHttpController { | ||
#getRefreshTokenCookie(res, req) { | ||
const cookieHeader = this.getCookie(req) | ||
|
||
const signedToken = extractRefreshTokenFromCookie(cookieHeader) | ||
if (!signedToken) return null | ||
|
||
const unsignedToken = signature.unsign(signedToken.slice(2), process.env.COOKIE_SECRET) | ||
if (unsignedToken !== false) { | ||
return unsignedToken | ||
} else { | ||
// this.#setRefreshTokenCookie(res, signedToken, true) | ||
throw new Error(ERROR_STATUES.INCORRECT_TOKEN.message, { | ||
cause: { | ||
status: ERROR_STATUES.INCORRECT_TOKEN.status, | ||
message: ERROR_STATUES.INCORRECT_TOKEN.message, | ||
}, | ||
}) | ||
} | ||
} | ||
|
||
#getAccessTokenFromHeader(req) { | ||
const token = req.getHeader("authorization")?.split(" ")?.[1] | ||
return token || null | ||
} | ||
|
||
async login(res, req) { | ||
try { | ||
const refresh_token = this.#getRefreshTokenCookie(res, req) | ||
const access_token = this.#getAccessTokenFromHeader(req) | ||
|
||
const { login, password, device_id } = await this.parseJsonBody(res) | ||
if (!device_id) { | ||
throw new Error(ERROR_STATUES.DEVICE_ID_MISSED.message, { | ||
cause: { status: ERROR_STATUES.DEVICE_ID_MISSED.status, message: ERROR_STATUES.DEVICE_ID_MISSED.message }, | ||
}) | ||
} | ||
|
||
const userAuthOperation = ServiceLocatorContainer.use("UserAuthOperation") | ||
const userInfo = { device_id } | ||
|
||
if (login && password) { | ||
Object.assign(userInfo, { login, password }) | ||
} else if (access_token || refresh_token) { | ||
userInfo.token = access_token || refresh_token | ||
} else { | ||
throw new Error(ERROR_STATUES.MISSING_AUTH_CREDENTIALS.message, { | ||
cause: { | ||
status: ERROR_STATUES.MISSING_AUTH_CREDENTIALS.status, | ||
message: ERROR_STATUES.MISSING_AUTH_CREDENTIALS.message, | ||
}, | ||
}) | ||
} | ||
|
||
const { user, token: accessToken } = await userAuthOperation.perform(null, userInfo) | ||
|
||
const newRefreshToken = await userAuthOperation.createRefreshToken(user, device_id) | ||
|
||
const accessTokenExpiredAt = | ||
new Date(accessToken.updated_at).getTime() + process.env.JWT_ACCESS_TOKEN_EXPIRES_IN * 1000 | ||
|
||
this.setStatus(res, 200) | ||
.setRefreshToken(res, newRefreshToken.token) | ||
.sendResponse(res, { user, access_token: accessToken.token, expired_at: accessTokenExpiredAt }) | ||
} catch (err) { | ||
console.log(err) | ||
this.setStatus(res, err.cause?.status || 500).sendResponse(res, { | ||
message: err.cause?.message || ERROR_STATUES.INTERNAL_SERVER.message, | ||
}) | ||
} | ||
} | ||
|
||
async logout(res, req) { | ||
try { | ||
const refresh_token = this.#getRefreshTokenCookie(res, req) | ||
const access_token = this.#getAccessTokenFromHeader(req) | ||
|
||
const sessionService = ServiceLocatorContainer.use("SessionService") | ||
const userTokenRepo = ServiceLocatorContainer.use("UserTokenRepository") | ||
|
||
const accessTokenRecord = await userTokenRepo.findToken(access_token, null, "access") | ||
if (!accessTokenRecord) { | ||
throw new Error(ERROR_STATUES.MISSING_AUTH_CREDENTIALS.message, { | ||
cause: { | ||
status: ERROR_STATUES.MISSING_AUTH_CREDENTIALS.status, | ||
message: ERROR_STATUES.MISSING_AUTH_CREDENTIALS.message, | ||
}, | ||
}) | ||
} | ||
|
||
const refreshTokenRecord = await userTokenRepo.findToken(refresh_token, accessTokenRecord.device_id, "refresh") | ||
|
||
if (!refreshTokenRecord) { | ||
throw new Error(ERROR_STATUES.INCORRECT_TOKEN.message, { | ||
cause: { status: ERROR_STATUES.INCORRECT_TOKEN.status, message: ERROR_STATUES.INCORRECT_TOKEN.message }, | ||
}) | ||
} | ||
|
||
const userId = refreshTokenRecord?.user_id | ||
|
||
const ws = sessionService.getUserDevices(userId).find((el) => el.deviceId === refreshTokenRecord.device_id)?.ws | ||
|
||
const userLogoutOperation = ServiceLocatorContainer.use("UserLogoutOperation") | ||
await userLogoutOperation.perform(ws) | ||
|
||
this.setStatus(res, 200).setRefreshToken(res, refreshTokenRecord.token, true).sendResponse(res, { success: true }) | ||
} catch (err) { | ||
console.log(err) | ||
this.setStatus(res, err.cause?.status || 500).sendResponse(res, { | ||
message: err.cause?.message || ERROR_STATUES.INTERNAL_SERVER.message, | ||
}) | ||
} | ||
} | ||
} | ||
|
||
export default new HttpAuthController() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import BaseController from "@sama/common/controller.js" | ||
|
||
import signature from "cookie-signature" | ||
|
||
export default class BaseHttpController extends BaseController { | ||
async parseJsonBody(res) { | ||
return new Promise((resolve, reject) => { | ||
let buffer = Buffer.alloc(0) | ||
res.onData((chunk, isLast) => { | ||
buffer = Buffer.concat([buffer, Buffer.from(chunk)]) | ||
if (isLast) { | ||
try { | ||
resolve(JSON.parse(buffer.toString())) | ||
} catch (error) { | ||
reject(new Error("Invalid JSON input")) | ||
} | ||
} | ||
}) | ||
|
||
res.onAborted(() => reject(new Error("Request aborted"))) | ||
}) | ||
} | ||
|
||
#setCorsHeaders(res) { | ||
res.writeHeader("Access-Control-Allow-Origin", process.env.CORS_ORIGIN || "*") | ||
res.writeHeader("Access-Control-Allow-Credentials", "true") | ||
res.writeHeader("Access-Control-Allow-Methods", "POST") | ||
res.writeHeader("Access-Control-Allow-Headers", "Content-Type, Authorization") | ||
} | ||
|
||
getCookie(req) { | ||
return req.getHeader("cookie") | ||
} | ||
|
||
setStatus(res, status) { | ||
res.writeStatus(`${status}`) | ||
return this | ||
} | ||
|
||
setRefreshToken(res, token, isRemove = false) { | ||
const signedToken = `s:` + signature.sign(token, process.env.COOKIE_SECRET) | ||
res.writeHeader( | ||
"Set-Cookie", | ||
`refresh_token=${signedToken}; Max-Age=${isRemove ? 0 : process.env.JWT_REFRESH_TOKEN_EXPIRES_IN}; HttpOnly; SameSite=Lax; Secure;` | ||
) | ||
return this | ||
} | ||
|
||
sendResponse(res, data) { | ||
this.#setCorsHeaders(res) | ||
res.end(JSON.stringify(data)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export default function extractRefreshTokenFromCookie(cookieHeader) { | ||
return cookieHeader | ||
? cookieHeader | ||
.split("; ") | ||
.find((cookie) => cookie.startsWith("refresh_token=")) | ||
?.split("=")[1] | ||
: null | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.