@@ -2,26 +2,28 @@ import { IdMap } from "medusa-test-utils"
|
|||||||
import { request } from "../../../../../helpers/test-request"
|
import { request } from "../../../../../helpers/test-request"
|
||||||
import { UserServiceMock } from "../../../../../services/__mocks__/user"
|
import { UserServiceMock } from "../../../../../services/__mocks__/user"
|
||||||
|
|
||||||
describe("POST /admin/users/:id/reset-password-token", () => {
|
describe("POST /admin/users/password-token", () => {
|
||||||
describe("successfully generates reset password token", () => {
|
describe("successfully generates reset password token", () => {
|
||||||
let subject
|
let subject
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
subject = await request(
|
subject = await request("POST", `/admin/users/password-token`, {
|
||||||
"POST",
|
payload: {
|
||||||
`/admin/users/${IdMap.getId("test-user")}/reset-password-token`,
|
email: "vandijk@test.dk",
|
||||||
{
|
},
|
||||||
adminSession: {
|
adminSession: {
|
||||||
jwt: {
|
jwt: {
|
||||||
userId: IdMap.getId("admin_user"),
|
userId: IdMap.getId("admin_user"),
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
)
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
afterAll(() => {
|
it("calls UserService retrieve", () => {
|
||||||
jest.clearAllMocks()
|
expect(UserServiceMock.retrieveByEmail).toHaveBeenCalledTimes(1)
|
||||||
|
expect(UserServiceMock.retrieveByEmail).toHaveBeenCalledWith(
|
||||||
|
"vandijk@test.dk"
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("calls UserService generateResetPasswordToken", () => {
|
it("calls UserService generateResetPasswordToken", () => {
|
||||||
@@ -29,12 +31,12 @@ describe("POST /admin/users/:id/reset-password-token", () => {
|
|||||||
1
|
1
|
||||||
)
|
)
|
||||||
expect(UserServiceMock.generateResetPasswordToken).toHaveBeenCalledWith(
|
expect(UserServiceMock.generateResetPasswordToken).toHaveBeenCalledWith(
|
||||||
IdMap.getId("test-user")
|
IdMap.getId("vandijk")
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("returns 200", () => {
|
it("returns 204", () => {
|
||||||
expect(subject.status).toEqual(200)
|
expect(subject.status).toEqual(204)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import jwt from "jsonwebtoken"
|
|||||||
import { request } from "../../../../../helpers/test-request"
|
import { request } from "../../../../../helpers/test-request"
|
||||||
import { UserServiceMock } from "../../../../../services/__mocks__/user"
|
import { UserServiceMock } from "../../../../../services/__mocks__/user"
|
||||||
|
|
||||||
describe("POST /admin/users/:id/reset-password", () => {
|
describe("POST /admin/users/reset-password", () => {
|
||||||
describe("successfully resets password", () => {
|
describe("successfully resets password", () => {
|
||||||
let subject
|
let subject
|
||||||
|
|
||||||
@@ -13,42 +13,37 @@ describe("POST /admin/users/:id/reset-password", () => {
|
|||||||
|
|
||||||
it("calls UserService setPassword", async () => {
|
it("calls UserService setPassword", async () => {
|
||||||
const exp = Math.floor(Date.now() / 1000) + 60 * 15
|
const exp = Math.floor(Date.now() / 1000) + 60 * 15
|
||||||
const token = jwt.sign(
|
|
||||||
{
|
|
||||||
userId: "test-user-id",
|
|
||||||
name: "Oliver Juhl",
|
|
||||||
email: "oliver@test.dk",
|
|
||||||
exp,
|
|
||||||
},
|
|
||||||
"123456789hash"
|
|
||||||
)
|
|
||||||
|
|
||||||
subject = await request(
|
subject = await request("POST", `/admin/users/reset-password`, {
|
||||||
"POST",
|
payload: {
|
||||||
`/admin/users/test-user-id/reset-password`,
|
email: "vandijk@test.dk",
|
||||||
{
|
token: jwt.sign(
|
||||||
payload: {
|
{
|
||||||
token,
|
user_id: IdMap.getId("vandijk"),
|
||||||
password: "new-password",
|
name: "Virgil Van Dijk",
|
||||||
},
|
email: "vandijk@test.dk",
|
||||||
adminSession: {
|
exp,
|
||||||
jwt: {
|
|
||||||
userId: IdMap.getId("admin_user"),
|
|
||||||
},
|
},
|
||||||
|
"1234"
|
||||||
|
),
|
||||||
|
password: "new-password",
|
||||||
|
},
|
||||||
|
adminSession: {
|
||||||
|
jwt: {
|
||||||
|
userId: IdMap.getId("admin_user"),
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
)
|
})
|
||||||
expect(UserServiceMock.setPassword).toHaveBeenCalledTimes(1)
|
expect(UserServiceMock.setPassword).toHaveBeenCalledTimes(1)
|
||||||
expect(UserServiceMock.setPassword).toHaveBeenCalledWith(
|
expect(UserServiceMock.setPassword).toHaveBeenCalledWith(
|
||||||
"test-user-id",
|
IdMap.getId("vandijk"),
|
||||||
"new-password"
|
"new-password"
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("returns updated user", () => {
|
it("returns updated user", () => {
|
||||||
expect(subject.body._id).toEqual("test-user-id")
|
expect(subject.body._id).toEqual(IdMap.getId("vandijk"))
|
||||||
})
|
})
|
||||||
|
|
||||||
it("returns 200", () => {
|
it("returns 200", () => {
|
||||||
expect(subject.status).toEqual(200)
|
expect(subject.status).toEqual(200)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -10,20 +10,20 @@ export default app => {
|
|||||||
route.get("/:user_id", middlewares.wrap(require("./get-user").default))
|
route.get("/:user_id", middlewares.wrap(require("./get-user").default))
|
||||||
|
|
||||||
route.post("/", middlewares.wrap(require("./create-user").default))
|
route.post("/", middlewares.wrap(require("./create-user").default))
|
||||||
route.post("/:user_id", middlewares.wrap(require("./update-user").default))
|
|
||||||
route.post(
|
route.post(
|
||||||
"/:user_id/set-password",
|
"/password-token",
|
||||||
middlewares.wrap(require("./set-password").default)
|
|
||||||
)
|
|
||||||
route.post(
|
|
||||||
"/:user_id/reset-password-token",
|
|
||||||
middlewares.wrap(require("./reset-password-token").default)
|
middlewares.wrap(require("./reset-password-token").default)
|
||||||
)
|
)
|
||||||
|
|
||||||
route.post(
|
route.post(
|
||||||
"/:user_id/reset-password",
|
"/reset-password",
|
||||||
middlewares.wrap(require("./reset-password").default)
|
middlewares.wrap(require("./reset-password").default)
|
||||||
)
|
)
|
||||||
|
route.post("/:user_id", middlewares.wrap(require("./update-user").default))
|
||||||
|
route.post(
|
||||||
|
"/:user_id/set-password",
|
||||||
|
middlewares.wrap(require("./set-password").default)
|
||||||
|
)
|
||||||
|
|
||||||
route.delete("/:user_id", middlewares.wrap(require("./delete-user").default))
|
route.delete("/:user_id", middlewares.wrap(require("./delete-user").default))
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,24 @@
|
|||||||
|
import { MedusaError, Validator } from "medusa-core-utils"
|
||||||
|
|
||||||
export default async (req, res) => {
|
export default async (req, res) => {
|
||||||
const { user_id } = req.params
|
const schema = Validator.object().keys({
|
||||||
|
email: Validator.string()
|
||||||
|
.email()
|
||||||
|
.required(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const { value, error } = schema.validate(req.body)
|
||||||
|
if (error) {
|
||||||
|
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const userService = req.scope.resolve("userService")
|
const userService = req.scope.resolve("userService")
|
||||||
const token = await userService.generateResetPasswordToken(user_id)
|
const user = await userService.retrieveByEmail(value.email)
|
||||||
res.json(token)
|
|
||||||
|
await userService.generateResetPasswordToken(user._id)
|
||||||
|
|
||||||
|
res.sendStatus(204)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ import { MedusaError, Validator } from "medusa-core-utils"
|
|||||||
import jwt from "jsonwebtoken"
|
import jwt from "jsonwebtoken"
|
||||||
|
|
||||||
export default async (req, res) => {
|
export default async (req, res) => {
|
||||||
const { user_id } = req.params
|
|
||||||
const schema = Validator.object().keys({
|
const schema = Validator.object().keys({
|
||||||
|
email: Validator.string()
|
||||||
|
.email()
|
||||||
|
.required(),
|
||||||
token: Validator.string().required(),
|
token: Validator.string().required(),
|
||||||
password: Validator.string().required(),
|
password: Validator.string().required(),
|
||||||
})
|
})
|
||||||
@@ -15,11 +17,12 @@ export default async (req, res) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const userService = req.scope.resolve("userService")
|
const userService = req.scope.resolve("userService")
|
||||||
let user = await userService.retrieve(user_id)
|
let user = await userService.retrieveByEmail(value.email)
|
||||||
|
|
||||||
const decodedToken = await jwt.verify(value.token, user.password_hash)
|
const decodedToken = await jwt.verify(value.token, user.password_hash)
|
||||||
if (!decodedToken) {
|
if (!decodedToken || decodedToken.user_id !== user._id) {
|
||||||
res.status(401).send("Invalid or expired password reset token")
|
res.status(401).send("Invalid or expired password reset token")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await userService.setPassword(user._id, value.password)
|
await userService.setPassword(user._id, value.password)
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ export const users = {
|
|||||||
email: "oliver@test.dk",
|
email: "oliver@test.dk",
|
||||||
password_hash: "hashed123456789",
|
password_hash: "hashed123456789",
|
||||||
},
|
},
|
||||||
|
vanDijk: {
|
||||||
|
_id: IdMap.getId("vandijk"),
|
||||||
|
email: "vandijk@test.dk",
|
||||||
|
password_hash: "hashed123456789",
|
||||||
|
},
|
||||||
jwtUser: {
|
jwtUser: {
|
||||||
_id: "test-user-id",
|
_id: "test-user-id",
|
||||||
email: "oliver@test.dk",
|
email: "oliver@test.dk",
|
||||||
@@ -43,6 +48,9 @@ export const UserServiceMock = {
|
|||||||
if (userId === IdMap.getId("test-user")) {
|
if (userId === IdMap.getId("test-user")) {
|
||||||
return Promise.resolve(users.testUser)
|
return Promise.resolve(users.testUser)
|
||||||
}
|
}
|
||||||
|
if (userId === IdMap.getId("vandijk")) {
|
||||||
|
return Promise.resolve(users.vanDijk)
|
||||||
|
}
|
||||||
// used for jwt token tests
|
// used for jwt token tests
|
||||||
if (userId === "test-user-id") {
|
if (userId === "test-user-id") {
|
||||||
return Promise.resolve(users.jwtUser)
|
return Promise.resolve(users.jwtUser)
|
||||||
@@ -66,6 +74,13 @@ export const UserServiceMock = {
|
|||||||
return Promise.resolve(undefined)
|
return Promise.resolve(undefined)
|
||||||
}),
|
}),
|
||||||
retrieveByEmail: jest.fn().mockImplementation(email => {
|
retrieveByEmail: jest.fn().mockImplementation(email => {
|
||||||
|
if (email === "vandijk@test.dk") {
|
||||||
|
return Promise.resolve({
|
||||||
|
_id: IdMap.getId("vandijk"),
|
||||||
|
email,
|
||||||
|
password_hash: "1234",
|
||||||
|
})
|
||||||
|
}
|
||||||
if (email === "oliver@test.dk") {
|
if (email === "oliver@test.dk") {
|
||||||
return bcrypt
|
return bcrypt
|
||||||
.hash("123456789", 10)
|
.hash("123456789", 10)
|
||||||
|
|||||||
@@ -4522,6 +4522,14 @@ media-typer@0.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||||
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
|
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
|
||||||
|
|
||||||
|
medusa-core-utils@^0.3.0:
|
||||||
|
version "0.1.39"
|
||||||
|
resolved "https://registry.yarnpkg.com/medusa-core-utils/-/medusa-core-utils-0.1.39.tgz#d57816c9bd43f9a92883650c1e66add1665291df"
|
||||||
|
integrity sha512-R8+U1ile7if+nR6Cjh5exunx0ETV0OfkWUUBUpz1KmHSDv0V0CcvQqU9lcZesPFDEbu3Y2iEjsCqidVA4nG2nQ==
|
||||||
|
dependencies:
|
||||||
|
"@hapi/joi" "^16.1.8"
|
||||||
|
joi-objectid "^3.0.1"
|
||||||
|
|
||||||
medusa-interfaces@^0.1.27:
|
medusa-interfaces@^0.1.27:
|
||||||
version "0.1.27"
|
version "0.1.27"
|
||||||
resolved "https://registry.yarnpkg.com/medusa-interfaces/-/medusa-interfaces-0.1.27.tgz#e77f9a9f82a7118eac8b35c1498ef8a5cec78898"
|
resolved "https://registry.yarnpkg.com/medusa-interfaces/-/medusa-interfaces-0.1.27.tgz#e77f9a9f82a7118eac8b35c1498ef8a5cec78898"
|
||||||
@@ -4529,6 +4537,13 @@ medusa-interfaces@^0.1.27:
|
|||||||
dependencies:
|
dependencies:
|
||||||
mongoose "^5.8.0"
|
mongoose "^5.8.0"
|
||||||
|
|
||||||
|
medusa-test-utils@^0.3.0:
|
||||||
|
version "0.1.39"
|
||||||
|
resolved "https://registry.yarnpkg.com/medusa-test-utils/-/medusa-test-utils-0.1.39.tgz#b7c166006a2fa4f02e52ab3bfafc19a3ae787f3e"
|
||||||
|
integrity sha512-M/Br8/HYvl7x2oLnme4NxdQwoyV0XUyOWiCyvPp7q1HUTB684lhJf1MikZVrcSjsh2L1rpyi3GRbKdf4cpJWvw==
|
||||||
|
dependencies:
|
||||||
|
mongoose "^5.8.0"
|
||||||
|
|
||||||
memory-pager@^1.0.2:
|
memory-pager@^1.0.2:
|
||||||
version "1.5.0"
|
version "1.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5"
|
resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5"
|
||||||
|
|||||||
Reference in New Issue
Block a user