-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Logout feature #26
Merged
+467
−174
Merged
Logout feature #26
Changes from 4 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
924962b
[#187584914]added logout feature
solangeihirwe03 d7d519c
[starts #187584914] added logout feature
solangeihirwe03 d67c001
Merge branch 'develop' of https://github.com/atlp-rwanda/e-commerce-n…
solangeihirwe03 44d5be7
[finishes#187584914] logout feature
solangeihirwe03 4f858fe
Merge branch 'develop' into logout-feature
solangeihirwe03 ec5b378
[delivers##187584914] updated readme & swagger.json
solangeihirwe03 ea11270
[delivers##187584914] updated readme & swagger.json
solangeihirwe03 db5b134
Merge branch 'develop' of https://github.com/atlp-rwanda/e-commerce-n…
solangeihirwe03 e7e67b1
[deliveres #187584914] logout features completed
solangeihirwe03 e508e93
[deliveres #187584914] logout features completed
solangeihirwe03 3ed403c
Merge branch 'logout-feature' of https://github.com/atlp-rwanda/e-com…
solangeihirwe03 a3531b4
[delivers #187584914] finished logout feature
solangeihirwe03 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* eslint-disable require-jsdoc */ | ||
import { Model, DataTypes, Sequelize } from "sequelize"; | ||
|
||
interface TokenAttributes { | ||
id: number; | ||
userId: number; | ||
device: string; | ||
accessToken: string; | ||
createdAt: Date; | ||
updatedAt: Date; | ||
expiresAt: Date; | ||
} | ||
|
||
module.exports = (sequelize: Sequelize) => { | ||
class Tokens extends Model<TokenAttributes> implements TokenAttributes { | ||
declare id: number; | ||
declare userId: number; | ||
declare device: string; | ||
declare accessToken: string; | ||
declare createdAt: Date; | ||
declare updatedAt: Date; | ||
declare expiresAt: Date; | ||
} | ||
|
||
Tokens.init( | ||
{ | ||
id: { | ||
type: DataTypes.INTEGER, | ||
autoIncrement: true, | ||
primaryKey: true | ||
}, | ||
userId: { | ||
type: new DataTypes.INTEGER(), | ||
allowNull: false | ||
}, | ||
device: { | ||
type: new DataTypes.STRING(280), | ||
allowNull: false | ||
}, | ||
accessToken: { | ||
type: new DataTypes.STRING(280), | ||
allowNull: false | ||
}, | ||
createdAt: { | ||
field: "createdAt", | ||
type: DataTypes.DATE, | ||
allowNull: false, | ||
defaultValue: DataTypes.NOW | ||
}, | ||
updatedAt: { | ||
field: "updatedAt", | ||
type: DataTypes.DATE, | ||
allowNull: false, | ||
defaultValue: DataTypes.NOW | ||
}, | ||
expiresAt: { | ||
type: DataTypes.DATE, | ||
allowNull: false | ||
} | ||
}, | ||
{ | ||
sequelize, | ||
tableName: "tokens", | ||
timestamps: true, | ||
modelName: "Tokens" | ||
} | ||
); | ||
|
||
return Tokens; | ||
}; |
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 |
---|---|---|
|
@@ -10,51 +10,115 @@ import authRepositories from "../repository/authRepositories"; | |
import { sendVerificationEmail } from "../../../services/sendEmail"; | ||
|
||
const registerUser = async (req: Request, res: Response): Promise<void> => { | ||
try { | ||
const register: UsersAttributes = await userRepositories.createUser(req.body); | ||
const token: string = generateToken(register.id); | ||
const session = { userId: register.id, device: req.headers["user-device"], token: token, otp: null }; | ||
await authRepositories.createSession(session); | ||
await sendVerificationEmail(register.email, "Verification Email", `${process.env.SERVER_URL_PRO}/api/auth/verify-email/${token}`); | ||
res.status(httpStatus.CREATED).json({ message: "Account created successfully. Please check email to verify account.", data: { user: register } }) | ||
} catch (error) { | ||
res.status(httpStatus.INTERNAL_SERVER_ERROR).json({ status: httpStatus.INTERNAL_SERVER_ERROR, message: error.message }); | ||
} | ||
|
||
} | ||
try { | ||
const register: UsersAttributes = await userRepositories.createUser( | ||
req.body | ||
); | ||
const token: string = generateToken(register.id); | ||
const session = { | ||
userId: register.id, | ||
device: req.headers["user-device"], | ||
token: token, | ||
otp: null, | ||
}; | ||
await authRepositories.createSession(session); | ||
await sendVerificationEmail( | ||
register.email, | ||
"Verification Email", | ||
`${process.env.SERVER_URL_PRO}/api/auth/verify-email/${token}` | ||
); | ||
res.status(httpStatus.CREATED).json({ | ||
message: | ||
"Account created successfully. Please check email to verify account.", | ||
data: { user: register }, | ||
}); | ||
} catch (error) { | ||
res.status(httpStatus.INTERNAL_SERVER_ERROR).json({ | ||
status: httpStatus.INTERNAL_SERVER_ERROR, | ||
message: error.message, | ||
}); | ||
} | ||
}; | ||
|
||
const sendVerifyEmail = async (req: any, res: Response) => { | ||
try { | ||
await sendVerificationEmail(req.user.email, "Verification Email", `${process.env.SERVER_URL_PRO}/api/auth/verify-email/${req.session.token}`); | ||
res.status(httpStatus.OK).json({ status: httpStatus.OK, message: "Verification email sent successfully." }); | ||
} catch (error) { | ||
return res.status(httpStatus.INTERNAL_SERVER_ERROR).json({ status: httpStatus.INTERNAL_SERVER_ERROR, message: error.message }); | ||
} | ||
} | ||
try { | ||
await sendVerificationEmail( | ||
req.user.email, | ||
"Verification Email", | ||
`${process.env.SERVER_URL_PRO}/api/auth/verify-email/${req.session.token}` | ||
); | ||
res.status(httpStatus.OK).json({ | ||
status: httpStatus.OK, | ||
message: "Verification email sent successfully.", | ||
}); | ||
} catch (error) { | ||
return res.status(httpStatus.INTERNAL_SERVER_ERROR).json({ | ||
status: httpStatus.INTERNAL_SERVER_ERROR, | ||
message: error.message, | ||
}); | ||
} | ||
}; | ||
|
||
const verifyEmail = async (req: any, res: Response) => { | ||
try { | ||
await authRepositories.destroySession(req.user.id, req.session.token) | ||
await authRepositories.UpdateUserByAttributes("isVerified", true, "id", req.user.id); | ||
res.status(httpStatus.OK).json({ status: httpStatus.OK, message: "Account verified successfully, now login." }); | ||
} catch (error) { | ||
return res.status(httpStatus.INTERNAL_SERVER_ERROR).json({ status: httpStatus.INTERNAL_SERVER_ERROR, message: error.message }); | ||
} | ||
} | ||
|
||
try { | ||
await authRepositories.destroySession(req.user.id, req.session.token); | ||
await authRepositories.UpdateUserByAttributes( | ||
"isVerified", | ||
true, | ||
"id", | ||
req.user.id | ||
); | ||
res.status(httpStatus.OK).json({ | ||
status: httpStatus.OK, | ||
message: "Account verified successfully, now login.", | ||
}); | ||
} catch (error) { | ||
return res.status(httpStatus.INTERNAL_SERVER_ERROR).json({ | ||
status: httpStatus.INTERNAL_SERVER_ERROR, | ||
message: error.message, | ||
}); | ||
} | ||
}; | ||
|
||
const loginUser = async (req: Request, res: Response) => { | ||
try { | ||
const userId = (req as IRequest).loginUserId; | ||
const token = generateToken(userId); | ||
const session = { userId, device: req.headers["user-device"], token: token, otp: null }; | ||
await userRepositories.createSession(session); | ||
res.status(httpStatus.OK).json({ message: "Logged in successfully", data: { token } }); | ||
} | ||
catch (err) { | ||
return res.status(httpStatus.INTERNAL_SERVER_ERROR).json({ message: "Server error", data: err.message }); | ||
} | ||
} | ||
try { | ||
const userId = (req as IRequest).loginUserId; | ||
const token = generateToken(userId); | ||
const session = { | ||
userId, | ||
device: req.headers["user-device"], | ||
token: token, | ||
otp: null, | ||
}; | ||
await userRepositories.createSession(session); | ||
res | ||
.status(httpStatus.OK) | ||
.json({ message: "Logged in successfully", data: { token } }); | ||
} catch (err) { | ||
return res | ||
.status(httpStatus.INTERNAL_SERVER_ERROR) | ||
.json({ message: "Server error", data: err.message }); | ||
} | ||
}; | ||
|
||
const logoutUser = async (req: Request, res: Response) => { | ||
try { | ||
await authRepositories.invalidateToken((req as IRequest).token); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You have to use |
||
res.status(httpStatus.OK).json({ message: "Successfully logged out" }); | ||
} catch (err) { | ||
return res | ||
.status(httpStatus.INTERNAL_SERVER_ERROR) | ||
.json({ | ||
status: httpStatus.INTERNAL_SERVER_ERROR, | ||
message: "Server error", | ||
}); | ||
} | ||
}; | ||
|
||
export default { registerUser, sendVerifyEmail, verifyEmail, loginUser } | ||
export default { | ||
registerUser, | ||
sendVerifyEmail, | ||
verifyEmail, | ||
loginUser, | ||
logoutUser, | ||
}; |
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 |
---|---|---|
|
@@ -27,4 +27,16 @@ const destroySession = async (userId: number, token:string) =>{ | |
return await Session.destroy({ where: {userId, token } }); | ||
} | ||
|
||
export default { createUser, createSession, findUserByAttributes, destroySession, UpdateUserByAttributes, findSessionByUserId } | ||
const invalidateToken = async (token: string) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove this |
||
return await Session.destroy({ where: { token } }); | ||
}; | ||
|
||
export default { | ||
createUser, | ||
createSession, | ||
findUserByAttributes, | ||
destroySession, | ||
UpdateUserByAttributes, | ||
findSessionByUserId, | ||
invalidateToken, | ||
}; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The access is not
Public
, should bePrivate
. Because you can't access Logout without Logged-In.