Adds medusa-plugin-permissions (#12)
This commit is contained in:
committed by
GitHub
parent
bc5dc5fab4
commit
f6d5180e5f
9
packages/medusa-plugin-permissions/.babelrc
Normal file
9
packages/medusa-plugin-permissions/.babelrc
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"plugins": ["@babel/plugin-proposal-class-properties"],
|
||||
"presets": ["@babel/preset-env"],
|
||||
"env": {
|
||||
"test": {
|
||||
"plugins": ["@babel/plugin-transform-runtime"]
|
||||
}
|
||||
}
|
||||
}
|
||||
8
packages/medusa-plugin-permissions/.gitignore
vendored
Normal file
8
packages/medusa-plugin-permissions/.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
dist/
|
||||
node_modules/
|
||||
.DS_store
|
||||
.env*
|
||||
/*.js
|
||||
!index.js
|
||||
yarn.lock
|
||||
yarn-error.log
|
||||
7
packages/medusa-plugin-permissions/.prettierrc
Normal file
7
packages/medusa-plugin-permissions/.prettierrc
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"endOfLine": "lf",
|
||||
"semi": false,
|
||||
"singleQuote": false,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5"
|
||||
}
|
||||
35
packages/medusa-plugin-permissions/package.json
Normal file
35
packages/medusa-plugin-permissions/package.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "medusa-plugin-permissions",
|
||||
"version": "1.0.0",
|
||||
"description": "Role permission for Medusa core",
|
||||
"main": "dist/index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/medusajs/medusa",
|
||||
"directory": "packages/medusa-plugin-permissions"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "babel src --out-dir dist/ --ignore **/__tests__",
|
||||
"prepare": "cross-env NODE_ENV=production npm run build",
|
||||
"watch": "babel -w src --out-dir dist/ --ignore **/__tests__",
|
||||
"test": "jest"
|
||||
},
|
||||
"author": "Oliver Juhl",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.7.5",
|
||||
"@babel/core": "^7.7.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.7.4",
|
||||
"@babel/plugin-transform-runtime": "^7.7.6",
|
||||
"@babel/preset-env": "^7.7.5",
|
||||
"@babel/runtime": "^7.7.6",
|
||||
"cross-env": "^5.2.1",
|
||||
"jest": "^24.9.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"mongoose": "^5.8.0",
|
||||
"medusa-test-utils": "^1.0.0",
|
||||
"medusa-core-utils": "^1.0.0",
|
||||
"medusa-interfaces": "^1.0.0"
|
||||
}
|
||||
}
|
||||
14
packages/medusa-plugin-permissions/src/api/middlewares.js
Normal file
14
packages/medusa-plugin-permissions/src/api/middlewares.js
Normal file
@@ -0,0 +1,14 @@
|
||||
// This middleware is injected to ensure authorization of requests
|
||||
// Since this middleware uses the user object on the request, this should be
|
||||
// injected after authentication in the core middleware, hence we name
|
||||
// the middleware postAuth.
|
||||
export default postAuth = () => {
|
||||
return (err, req, res, next) => {
|
||||
const permissionService = req.scope.resolve("permissionService")
|
||||
if (permissionService.hasPermission(req.user, req.method, req.path)) {
|
||||
next()
|
||||
} else {
|
||||
res.status(422)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { IdMap } from "medusa-test-utils"
|
||||
|
||||
export const permissions = {
|
||||
productEditorPermission: {
|
||||
_id: IdMap.getId("product_editor"),
|
||||
name: "product_editor",
|
||||
permissions: [
|
||||
{
|
||||
method: "POST",
|
||||
endpoint: "/products",
|
||||
},
|
||||
{
|
||||
method: "GET",
|
||||
endpoint: "/products",
|
||||
},
|
||||
{
|
||||
method: "PUT",
|
||||
endpoint: "/products",
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
export const RoleModelMock = {
|
||||
create: jest.fn().mockReturnValue(Promise.resolve()),
|
||||
deleteOne: jest.fn().mockReturnValue(Promise.resolve()),
|
||||
findOne: jest.fn().mockImplementation(query => {
|
||||
if (query.name === "product_editor") {
|
||||
return Promise.resolve(permissions.productEditorPermission)
|
||||
}
|
||||
return Promise.resolve(undefined)
|
||||
}),
|
||||
updateOne: jest.fn().mockImplementation((query, update) => {
|
||||
return Promise.resolve()
|
||||
}),
|
||||
}
|
||||
13
packages/medusa-plugin-permissions/src/models/role.js
Normal file
13
packages/medusa-plugin-permissions/src/models/role.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { BaseModel } from "medusa-interfaces"
|
||||
|
||||
import PermissionSchema from "./schemas/permission"
|
||||
|
||||
class RoleModel extends BaseModel {
|
||||
static modelName = "Role"
|
||||
static schema = {
|
||||
name: { type: String, required: true, unique: true },
|
||||
permissions: { type: [PermissionSchema], required: true, default: [] },
|
||||
}
|
||||
}
|
||||
|
||||
export default RoleModel
|
||||
@@ -0,0 +1,6 @@
|
||||
import mongoose from "mongoose"
|
||||
|
||||
export default new mongoose.Schema({
|
||||
method: { type: String },
|
||||
endpoint: { type: String },
|
||||
})
|
||||
@@ -0,0 +1,15 @@
|
||||
import { IdMap } from "medusa-test-utils"
|
||||
|
||||
export const PermissionServiceMock = {
|
||||
hasPermission: jest.fn().mockImplementation((user, method, endpoint) => {
|
||||
if (user._id === IdMap.getId("test-user")) {
|
||||
return Promise.resolve(true)
|
||||
}
|
||||
}),
|
||||
}
|
||||
|
||||
const mock = jest.fn().mockImplementation(() => {
|
||||
return PermissionServiceMock
|
||||
})
|
||||
|
||||
export default mock
|
||||
@@ -0,0 +1,354 @@
|
||||
import mongoose from "mongoose"
|
||||
import { IdMap } from "medusa-test-utils"
|
||||
import PermissionService from "../permission"
|
||||
import { permissions, RoleModelMock } from "../../models/__mocks__/role"
|
||||
|
||||
describe("PermissionService", () => {
|
||||
describe("hasPermission", () => {
|
||||
let result
|
||||
let user = {
|
||||
_id: IdMap.getId("test-user"),
|
||||
email: "oliver@medusa.test",
|
||||
passwordHash: "123456789",
|
||||
metadata: {
|
||||
roles: ["product_editor"],
|
||||
},
|
||||
}
|
||||
const permissionService = new PermissionService({
|
||||
roleModel: RoleModelMock,
|
||||
})
|
||||
|
||||
beforeAll(async () => {
|
||||
jest.clearAllMocks()
|
||||
result = await permissionService.hasPermission(user, "POST", "/products")
|
||||
})
|
||||
|
||||
it("calls permission model functions", () => {
|
||||
expect(RoleModelMock.findOne).toHaveBeenCalledTimes(
|
||||
user.metadata.roles.length
|
||||
)
|
||||
})
|
||||
|
||||
it("successfully grants access to user", () => {
|
||||
expect(result).toEqual(true)
|
||||
})
|
||||
|
||||
it("succesfully denies access to user", async () => {
|
||||
const accessDenied = await permissionService.hasPermission(
|
||||
user,
|
||||
"CREATE",
|
||||
"/orders"
|
||||
)
|
||||
expect(accessDenied).toEqual(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe("retrieveRole", () => {
|
||||
let result
|
||||
const permissionService = new PermissionService({
|
||||
roleModel: RoleModelMock,
|
||||
})
|
||||
beforeAll(async () => {
|
||||
jest.clearAllMocks()
|
||||
|
||||
result = await permissionService.retrieveRole("product_editor")
|
||||
})
|
||||
|
||||
it("calls permission model functions", () => {
|
||||
expect(RoleModelMock.findOne).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it("successfully fetches product editor permissions", () => {
|
||||
expect(result).toEqual(permissions.productEditorPermission)
|
||||
})
|
||||
|
||||
it("throws if role with name does not exist", async () => {
|
||||
try {
|
||||
await permissionService.retrieveRole("product_editor")
|
||||
} catch (error) {
|
||||
expect(error.message).toEqual(
|
||||
"test_editor does not exist. Use method createRole to create it."
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("createRole", () => {
|
||||
const permissionService = new PermissionService({
|
||||
roleModel: RoleModelMock,
|
||||
})
|
||||
|
||||
beforeAll(async () => {
|
||||
jest.clearAllMocks()
|
||||
|
||||
const contentEditorPermissions = [
|
||||
{
|
||||
method: "POST",
|
||||
endpoint: "/contents",
|
||||
},
|
||||
{
|
||||
method: "GET",
|
||||
endpoint: "/contents",
|
||||
},
|
||||
{
|
||||
method: "PUT",
|
||||
endpoint: "/contents",
|
||||
},
|
||||
]
|
||||
|
||||
await permissionService.createRole(
|
||||
"content_editor",
|
||||
contentEditorPermissions
|
||||
)
|
||||
})
|
||||
|
||||
it("calls permission model functions", () => {
|
||||
expect(RoleModelMock.create).toHaveBeenCalledTimes(1)
|
||||
expect(RoleModelMock.create).toHaveBeenCalledWith({
|
||||
name: "content_editor",
|
||||
permissions: [
|
||||
{
|
||||
method: "POST",
|
||||
endpoint: "/contents",
|
||||
},
|
||||
{
|
||||
method: "GET",
|
||||
endpoint: "/contents",
|
||||
},
|
||||
{
|
||||
method: "PUT",
|
||||
endpoint: "/contents",
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
|
||||
it("throws if any permission is invalid", async () => {
|
||||
try {
|
||||
await permissionService.createRole("content_editor", [
|
||||
{
|
||||
method: "POST",
|
||||
endpoint: "/products",
|
||||
},
|
||||
{
|
||||
// Should fail since this is not a valid http request
|
||||
method: "FETCH",
|
||||
endpoint: "/products",
|
||||
},
|
||||
])
|
||||
} catch (err) {
|
||||
expect(err.message).toEqual("Permission is not valid")
|
||||
}
|
||||
})
|
||||
|
||||
it("throws if role with name already exists", async () => {
|
||||
try {
|
||||
await permissionService.createRole("product_editor", [
|
||||
{
|
||||
method: "POST",
|
||||
endpoint: "/order",
|
||||
},
|
||||
])
|
||||
} catch (err) {
|
||||
expect(err.message).toEqual("product_editor already exists")
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("grantRole", () => {
|
||||
const setMetadataMock = jest.fn().mockReturnValue(Promise.resolve())
|
||||
const userRetrieveMock = jest.fn().mockImplementation((data) => {
|
||||
if (data === IdMap.getId("permission-user")) {
|
||||
return Promise.resolve({
|
||||
_id: IdMap.getId("permission-user"),
|
||||
email: "oliver@test.dk",
|
||||
metadata: {
|
||||
roles: ["content_editor"],
|
||||
},
|
||||
})
|
||||
}
|
||||
if (data === IdMap.getId("user-without-roles")) {
|
||||
return Promise.resolve({
|
||||
_id: IdMap.getId("user-without-roles"),
|
||||
email: "oliver@test.dk",
|
||||
metadata: {},
|
||||
})
|
||||
}
|
||||
return Promise.resolve(undefined)
|
||||
})
|
||||
const permissionService = new PermissionService({
|
||||
roleModel: RoleModelMock,
|
||||
userService: {
|
||||
setMetadata: setMetadataMock,
|
||||
retrieve: userRetrieveMock,
|
||||
},
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it("successfully grants role to user", async () => {
|
||||
await permissionService.grantRole(
|
||||
IdMap.getId("permission-user"),
|
||||
"product_editor"
|
||||
)
|
||||
|
||||
expect(setMetadataMock).toHaveBeenCalledTimes(1)
|
||||
expect(setMetadataMock).toHaveBeenCalledWith(
|
||||
IdMap.getId("permission-user"),
|
||||
"roles",
|
||||
["content_editor", "product_editor"]
|
||||
)
|
||||
})
|
||||
|
||||
it("sets user metadata.roles to user that does not have metadata.roles", async () => {
|
||||
await permissionService.grantRole(
|
||||
IdMap.getId("user-without-roles"),
|
||||
"product_editor"
|
||||
)
|
||||
|
||||
expect(setMetadataMock).toHaveBeenCalledTimes(1)
|
||||
expect(setMetadataMock).toHaveBeenCalledWith(
|
||||
IdMap.getId("user-without-roles"),
|
||||
"roles",
|
||||
["product_editor"]
|
||||
)
|
||||
})
|
||||
|
||||
it("throws if user already has role", async () => {
|
||||
try {
|
||||
await permissionService.grantRole(
|
||||
IdMap.getId("permission-user"),
|
||||
"product_editor"
|
||||
)
|
||||
} catch (err) {
|
||||
expect(err.message).toEqual("User already has role: product_editor")
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("addPermission", () => {
|
||||
const permissionService = new PermissionService({
|
||||
roleModel: RoleModelMock,
|
||||
})
|
||||
|
||||
beforeAll(async () => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it("successfully adds permission", async () => {
|
||||
const toAdd = {
|
||||
method: "POST",
|
||||
endpoint: "/products",
|
||||
}
|
||||
await permissionService.addPermission("product_editor", toAdd)
|
||||
|
||||
expect(RoleModelMock.updateOne).toHaveBeenCalledTimes(1)
|
||||
expect(RoleModelMock.updateOne).toHaveBeenCalledWith(
|
||||
{ _id: IdMap.getId("product_editor") },
|
||||
{
|
||||
$push: { permissions: { method: "POST", endpoint: "/products" } },
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it("throws if permission is not valid", async () => {
|
||||
const toAdd = {
|
||||
method: "POST",
|
||||
endpoint: 1234,
|
||||
}
|
||||
|
||||
try {
|
||||
await permissionService.addPermission("product_editor", toAdd)
|
||||
} catch (err) {
|
||||
expect(err.message).toEqual("Permission is not valid")
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("removePermission", () => {
|
||||
const permissionService = new PermissionService({
|
||||
roleModel: RoleModelMock,
|
||||
})
|
||||
|
||||
beforeAll(async () => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it("successfully removes permission", async () => {
|
||||
const toRemove = {
|
||||
method: "POST",
|
||||
endpoint: "/products",
|
||||
}
|
||||
await permissionService.removePermission("product_editor", toRemove)
|
||||
|
||||
expect(RoleModelMock.updateOne).toHaveBeenCalledTimes(1)
|
||||
expect(RoleModelMock.updateOne).toHaveBeenCalledWith(
|
||||
{ _id: IdMap.getId("product_editor") },
|
||||
{
|
||||
$pull: { permissions: { method: "POST", endpoint: "/products" } },
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it("throws if permission is not valid", async () => {
|
||||
const update = {
|
||||
method: "FETCH",
|
||||
endpoint: "/cart",
|
||||
}
|
||||
|
||||
try {
|
||||
await permissionService.addPermission("product_editor", update)
|
||||
} catch (err) {
|
||||
expect(err.message).toEqual("Permission is not valid")
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("revokeRole", () => {
|
||||
const setMetadataMock = jest.fn().mockReturnValue(Promise.resolve())
|
||||
const userRetrieveMock = jest.fn().mockReturnValue(
|
||||
Promise.resolve({
|
||||
_id: IdMap.getId("product_editor"),
|
||||
email: "oliver@test.dk",
|
||||
metadata: {
|
||||
roles: ["product_editor"],
|
||||
},
|
||||
})
|
||||
)
|
||||
const permissionService = new PermissionService({
|
||||
roleModel: RoleModelMock,
|
||||
userService: {
|
||||
setMetadata: setMetadataMock,
|
||||
retrieve: userRetrieveMock,
|
||||
},
|
||||
})
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it("successfully revokes a role from user", async () => {
|
||||
await permissionService.revokeRole(
|
||||
IdMap.getId("product_editor"),
|
||||
"product_editor"
|
||||
)
|
||||
|
||||
expect(setMetadataMock).toHaveBeenCalledTimes(1)
|
||||
expect(setMetadataMock).toHaveBeenCalledWith(
|
||||
IdMap.getId("product_editor"),
|
||||
"roles",
|
||||
[]
|
||||
)
|
||||
})
|
||||
|
||||
it("succeeds idempotently if user does not have the role to delete", async () => {
|
||||
await permissionService.revokeRole(
|
||||
IdMap.getId("product_editor"),
|
||||
"content_editor"
|
||||
)
|
||||
|
||||
expect(setMetadataMock).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
161
packages/medusa-plugin-permissions/src/services/permission.js
Normal file
161
packages/medusa-plugin-permissions/src/services/permission.js
Normal file
@@ -0,0 +1,161 @@
|
||||
import { BaseService } from "medusa-interfaces"
|
||||
import { Validator, MedusaError } from "medusa-core-utils"
|
||||
|
||||
class PermissionService extends BaseService {
|
||||
constructor({ userService, roleModel }) {
|
||||
super()
|
||||
|
||||
/** @private @const {UserService} */
|
||||
this.userService_ = userService
|
||||
|
||||
/** @private @const {RoleModel} */
|
||||
this.roleModel_ = roleModel
|
||||
}
|
||||
|
||||
validatePermission_(permission) {
|
||||
const schema = Validator.object({
|
||||
method: Validator.string().valid(
|
||||
"POST",
|
||||
"GET",
|
||||
"PUT",
|
||||
"PATCH",
|
||||
"DELETE",
|
||||
"CONNECT",
|
||||
"OPTIONS",
|
||||
"HEAD",
|
||||
"TRACE"
|
||||
),
|
||||
endpoint: Validator.string(),
|
||||
})
|
||||
|
||||
const { value, error } = schema.validate(permission)
|
||||
|
||||
if (error) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_ARGUMENT,
|
||||
"Permission is not valid"
|
||||
)
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
async retrieveRole(name) {
|
||||
const role = await this.roleModel_.findOne({ name }).catch((err) => {
|
||||
throw new MedusaError(MedusaError.Types.DB_ERROR, err.message)
|
||||
})
|
||||
|
||||
if (!role) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_FOUND,
|
||||
`${name} does not exist. Use method createRole to create it.`
|
||||
)
|
||||
}
|
||||
return role
|
||||
}
|
||||
|
||||
async hasPermission(user, method, endpoint) {
|
||||
for (let i = 0; i < user.metadata.roles.length; i++) {
|
||||
const role = user.metadata.roles[i]
|
||||
const permissions = await this.retrieveRole(role)
|
||||
return permissions.permissions.some((action) => {
|
||||
return action.method === method && action.endpoint === endpoint
|
||||
})
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
async createRole(roleName, permissions) {
|
||||
const validatedPermissions = permissions.map((permission) =>
|
||||
this.validatePermission_(permission)
|
||||
)
|
||||
|
||||
return this.retrieveRole(roleName)
|
||||
.then((role) => {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_ARGUMENT,
|
||||
`${role.name} already exists`
|
||||
)
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.name === MedusaError.Types.NOT_FOUND) {
|
||||
return this.roleModel_.create({
|
||||
name: roleName,
|
||||
permissions: validatedPermissions,
|
||||
})
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async deleteRole(roleName) {
|
||||
const role = await this.retrieve(roleName)
|
||||
// Delete is idempotent, but we return a promise to allow then-chaining
|
||||
if (!role) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
return this.roleModel_
|
||||
.deleteOne({
|
||||
_id: role._id,
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new MedusaError(MedusaError.Types.DB_ERROR, err.message)
|
||||
})
|
||||
}
|
||||
|
||||
async addPermission(roleName, permission) {
|
||||
const role = await this.retrieveRole(roleName)
|
||||
const validatedPermission = this.validatePermission_(permission)
|
||||
|
||||
return this.roleModel_.updateOne(
|
||||
{ _id: role._id },
|
||||
{ $push: { permissions: validatedPermission } }
|
||||
)
|
||||
}
|
||||
|
||||
async removePermission(roleName, permission) {
|
||||
const role = await this.retrieveRole(roleName)
|
||||
const validatedPermission = this.validatePermission_(permission)
|
||||
|
||||
return this.roleModel_.updateOne(
|
||||
{ _id: role._id },
|
||||
{ $pull: { permissions: validatedPermission } }
|
||||
)
|
||||
}
|
||||
|
||||
async grantRole(userId, roleName) {
|
||||
const role = await this.retrieveRole(roleName)
|
||||
const user = await this.userService_.retrieve(userId)
|
||||
|
||||
if (!user.metadata.roles) {
|
||||
return this.userService_.setMetadata(userId, "roles", [roleName])
|
||||
}
|
||||
|
||||
if (user.metadata.roles.includes(role.name)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.DB_ERROR,
|
||||
`User already has role: ${role.name}`
|
||||
)
|
||||
}
|
||||
|
||||
user.metadata.roles.push(roleName)
|
||||
return this.userService_.setMetadata(userId, "roles", user.metadata.roles)
|
||||
}
|
||||
|
||||
async revokeRole(userId, roleName) {
|
||||
const user = await this.userService_.retrieve(userId)
|
||||
|
||||
if (!user.metadata.roles || !user.metadata.roles.includes(roleName)) {
|
||||
// revokeRole is idempotent, we return a promise to allow then-chaining
|
||||
return Promise.resolve()
|
||||
}
|
||||
// remove role from metadata.roles
|
||||
const newRoles = user.metadata.roles.filter((r) => r !== roleName)
|
||||
|
||||
return this.userService_.setMetadata(userId, "roles", newRoles)
|
||||
}
|
||||
}
|
||||
|
||||
export default PermissionService
|
||||
@@ -4,5 +4,4 @@
|
||||
"singleQuote": false,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,11 @@ export const users = {
|
||||
email: "oliver@medusa.test",
|
||||
passwordHash: "123456789",
|
||||
},
|
||||
permissionUser: {
|
||||
_id: IdMap.getId("permissions-user"),
|
||||
email: "oliver@medusa.com",
|
||||
passwordHash: "123456789",
|
||||
},
|
||||
}
|
||||
|
||||
export const UserModelMock = {
|
||||
@@ -18,6 +23,9 @@ export const UserModelMock = {
|
||||
if (query._id === IdMap.getId("test-user")) {
|
||||
return Promise.resolve(users.testUser)
|
||||
}
|
||||
if (query._id === IdMap.getId("permission-user")) {
|
||||
return Promise.resolve(users.permissionUser)
|
||||
}
|
||||
return Promise.resolve(undefined)
|
||||
}),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user