Last active
November 11, 2022 07:54
-
-
Save imkarimkarim/77d920f26fac6096f8dbe09aaa56a99d to your computer and use it in GitHub Desktop.
strapi in app auth: only let authed users CUD their enteties, not other users... (i implemented for store and its child(product) content-type here but you can extend...)
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
"use strict"; | |
const { getStoreOfProduct, isUserOwnsStore } = require("../../../lib/utils"); | |
/** | |
* product service | |
*/ | |
const { createCoreService } = require("@strapi/strapi").factories; | |
module.exports = createCoreService("api::product.product", ({ strapi }) => ({ | |
async create(params) { | |
const storeId = params?.data?.store; | |
const authorized = await isUserOwnsStore(strapi, storeId); | |
if (authorized) { | |
const result = await super.create(params); | |
return result; | |
} | |
return null; | |
}, | |
async update(entityId, params) { | |
const storeId = await getStoreOfProduct(entityId); | |
const authorized1 = await isUserOwnsStore(strapi, storeId); | |
// only let user update to prev store id | |
const id = params?.data?.store; | |
const authorized2 = storeId == id; | |
if (authorized1 && authorized2) { | |
const result = await super.update(entityId, params); | |
return result; | |
} | |
return null; | |
}, | |
async delete(entityId) { | |
const storeId = await getStoreOfProduct(entityId); | |
const authorized = await isUserOwnsStore(strapi, storeId); | |
if (authorized) { | |
const result = await super.delete(entityId); | |
return result; | |
} | |
return 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
"use strict"; | |
const { isUserOwnsStore, isJwdUser } = require("../../../lib/utils"); | |
/** | |
* store service | |
*/ | |
const { createCoreService } = require("@strapi/strapi").factories; | |
module.exports = createCoreService("api::store.store", ({ strapi }) => ({ | |
async create(params) { | |
const id = params?.data?.users_permissions_user; | |
const authorized = isJwdUser(strapi, id); | |
if (authorized) { | |
const result = await super.create(params); | |
return result; | |
} | |
return null; | |
}, | |
async update(entityId, params) { | |
// only let user update to its own id | |
const id = params?.data?.users_permissions_user; | |
const authorized1 = isJwdUser(strapi, id); | |
const authorized2 = await isUserOwnsStore(strapi, entityId); | |
if (authorized1 && authorized2) { | |
const result = await super.update(entityId, params); | |
return result; | |
} | |
return null; | |
}, | |
async delete(entityId) { | |
const authorized = await isUserOwnsStore(strapi, entityId); | |
if (authorized) { | |
const result = await super.delete(entityId); | |
return result; | |
} | |
return 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
const notFound = -1; | |
/** | |
* check if user is who claim she(jwtId === userId) | |
*/ | |
const isJwdUser = (strapi, userId) => { | |
const ctx = strapi.requestContext.get(); | |
const jwtId = ctx?.state?.auth?.credentials?.id; | |
return jwtId == userId; | |
}; | |
const isUserOwnsStore = async (strapi, storeId) => { | |
const entity = await strapi.service("api::store.store").findOne(storeId, { | |
populate: "users_permissions_user", | |
}); | |
const id = entity?.users_permissions_user?.id || notFound; | |
const isAuthorized = isJwdUser(strapi, id); | |
return isAuthorized; | |
}; | |
const getStoreOfProduct = async (id) => { | |
const entity = await strapi.service("api::product.product").findOne(id, { | |
populate: "store", | |
}); | |
const storeId = entity?.store?.id || notFound; | |
return storeId; | |
}; | |
module.exports = { | |
isJwdUser, | |
isUserOwnsStore, | |
getStoreOfProduct, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment