{"version":3,"file":"_id_.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/admin/roles/[id].ts"],"sourcesContent":["/**\n * GET    /_emdash/api/admin/roles/:id — one role (id or slug)\n * PUT    /_emdash/api/admin/roles/:id — update name, description, level, policies\n * DELETE /_emdash/api/admin/roles/:id — delete (not built-in, not in use)\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { roleUpdateBody } from \"#api/schemas.js\";\nimport { invalidateAuthzCache } from \"#auth/authz.js\";\nimport { AuthzRepository } from \"#db/repositories/authz.js\";\n\nimport { authzErrorResponse } from \"./index.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tif (!emdash?.db) return apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\tconst denied = requirePerm(user, \"roles:read\");\n\tif (denied) return denied;\n\tif (!params.id) return apiError(\"MISSING_PARAM\", \"Role id required\", 400);\n\n\ttry {\n\t\tconst item = await new AuthzRepository(emdash.db).getRole(params.id);\n\t\tif (!item) return apiError(\"NOT_FOUND\", \"Role not found\", 404);\n\t\treturn apiSuccess({ item });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to get role\", \"ROLE_GET_ERROR\");\n\t}\n};\n\nexport const PUT: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tif (!emdash?.db) return apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\tconst denied = requirePerm(user, \"roles:manage\");\n\tif (denied) return denied;\n\tif (!params.id) return apiError(\"MISSING_PARAM\", \"Role id required\", 400);\n\n\ttry {\n\t\tconst body = await parseBody(request, roleUpdateBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst repo = new AuthzRepository(emdash.db);\n\n\t\t// Editing your own role is refused for the same reason self-demotion\n\t\t// is: an admin who removes roles:manage from their own role has no way\n\t\t// back. Another administrator must make that change.\n\t\tconst target = await repo.getRole(params.id);\n\t\tif (!target) return apiError(\"NOT_FOUND\", \"Role not found\", 404);\n\t\tif (user!.roleId === target.id && (body.policies !== undefined || body.level !== undefined)) {\n\t\t\treturn apiError(\n\t\t\t\t\"SELF_ROLE_CHANGE\",\n\t\t\t\t\"You cannot change the policies or level of your own role\",\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\tconst item = await repo.updateRole(target.id, body);\n\t\tinvalidateAuthzCache();\n\t\treturn apiSuccess({ item });\n\t} catch (error) {\n\t\treturn (\n\t\t\tauthzErrorResponse(error) ?? handleError(error, \"Failed to update role\", \"ROLE_UPDATE_ERROR\")\n\t\t);\n\t}\n};\n\nexport const DELETE: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tif (!emdash?.db) return apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\tconst denied = requirePerm(user, \"roles:manage\");\n\tif (denied) return denied;\n\tif (!params.id) return apiError(\"MISSING_PARAM\", \"Role id required\", 400);\n\n\ttry {\n\t\tawait new AuthzRepository(emdash.db).deleteRole(params.id);\n\t\tinvalidateAuthzCache();\n\t\treturn apiSuccess({ success: true });\n\t} catch (error) {\n\t\treturn (\n\t\t\tauthzErrorResponse(error) ?? handleError(error, \"Failed to delete role\", \"ROLE_DELETE_ERROR\")\n\t\t);\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAiBA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,aAAa;CAC1D,MAAM,EAAE,QAAQ,SAAS;AACzB,KAAI,CAAC,QAAQ,GAAI,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CACpF,MAAM,SAAS,YAAY,MAAM,aAAa;AAC9C,KAAI,OAAQ,QAAO;AACnB,KAAI,CAAC,OAAO,GAAI,QAAO,SAAS,iBAAiB,oBAAoB,IAAI;AAEzE,KAAI;EACH,MAAM,OAAO,MAAM,IAAI,gBAAgB,OAAO,GAAG,CAAC,QAAQ,OAAO,GAAG;AACpE,MAAI,CAAC,KAAM,QAAO,SAAS,aAAa,kBAAkB,IAAI;AAC9D,SAAO,WAAW,EAAE,MAAM,CAAC;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,sBAAsB,iBAAiB;;;AAInE,MAAa,MAAgB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACnE,MAAM,EAAE,QAAQ,SAAS;AACzB,KAAI,CAAC,QAAQ,GAAI,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CACpF,MAAM,SAAS,YAAY,MAAM,eAAe;AAChD,KAAI,OAAQ,QAAO;AACnB,KAAI,CAAC,OAAO,GAAI,QAAO,SAAS,iBAAiB,oBAAoB,IAAI;AAEzE,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,eAAe;AACrD,MAAI,aAAa,KAAK,CAAE,QAAO;EAE/B,MAAM,OAAO,IAAI,gBAAgB,OAAO,GAAG;EAK3C,MAAM,SAAS,MAAM,KAAK,QAAQ,OAAO,GAAG;AAC5C,MAAI,CAAC,OAAQ,QAAO,SAAS,aAAa,kBAAkB,IAAI;AAChE,MAAI,KAAM,WAAW,OAAO,OAAO,KAAK,aAAa,UAAa,KAAK,UAAU,QAChF,QAAO,SACN,oBACA,4DACA,IACA;EAGF,MAAM,OAAO,MAAM,KAAK,WAAW,OAAO,IAAI,KAAK;AACnD,wBAAsB;AACtB,SAAO,WAAW,EAAE,MAAM,CAAC;UACnB,OAAO;AACf,SACC,mBAAmB,MAAM,IAAI,YAAY,OAAO,yBAAyB,oBAAoB;;;AAKhG,MAAa,SAAmB,OAAO,EAAE,QAAQ,aAAa;CAC7D,MAAM,EAAE,QAAQ,SAAS;AACzB,KAAI,CAAC,QAAQ,GAAI,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CACpF,MAAM,SAAS,YAAY,MAAM,eAAe;AAChD,KAAI,OAAQ,QAAO;AACnB,KAAI,CAAC,OAAO,GAAI,QAAO,SAAS,iBAAiB,oBAAoB,IAAI;AAEzE,KAAI;AACH,QAAM,IAAI,gBAAgB,OAAO,GAAG,CAAC,WAAW,OAAO,GAAG;AAC1D,wBAAsB;AACtB,SAAO,WAAW,EAAE,SAAS,MAAM,CAAC;UAC5B,OAAO;AACf,SACC,mBAAmB,MAAM,IAAI,YAAY,OAAO,yBAAyB,oBAAoB"}