UNPKG

cnpmcore

Version:

Private NPM Registry for Enterprise

422 lines 36 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; import { Context, HTTPBody, HTTPContext, HTTPController, HTTPMethod, HTTPMethodEnum, HTTPParam, Inject } from 'egg'; import { ForbiddenError, NotFoundError, UnprocessableEntityError } from 'egg/errors'; import { getScopeAndName } from "../../common/PackageUtil.js"; import { AbstractController } from "./AbstractController.js"; let TeamController = class TeamController extends AbstractController { isAllowScopeOrg(orgName) { return this.config.cnpmcore.allowScopes.includes(`@${orgName}`); } // For allowScopes orgs, auto-ensure; for others, just look up async findOrg(orgName) { if (this.isAllowScopeOrg(orgName)) { return await this.orgService.ensureOrgForScope(`@${orgName}`); } return await this.orgService.findOrgByName(orgName); } async requireOrgWriteAccess(ctx, orgName) { const authorizedUser = await this.userRoleManager.requiredAuthorizedUser(ctx, 'setting'); if (this.isAllowScopeOrg(orgName)) { // allowScopes org: any authenticated user can operate, auto-ensure org const org = await this.orgService.ensureOrgForScope(`@${orgName}`); return { org, authorizedUser }; } // Non-allowScopes org: admin or org owner only const org = await this.orgService.findOrgByName(orgName); if (!org) { throw new NotFoundError(`Org "${orgName}" not found`); } const isAdmin = await this.userRoleManager.isAdmin(ctx); await this.orgService.requiredOrgOwnerOrAdmin(org.orgId, authorizedUser.userId, isAdmin); return { org, authorizedUser }; } async requireTeamWriteAccess(ctx, orgName, teamName) { const authorizedUser = await this.userRoleManager.requiredAuthorizedUser(ctx, 'setting'); const isAdmin = await this.userRoleManager.isAdmin(ctx); let org; if (this.isAllowScopeOrg(orgName)) { org = await this.orgService.ensureOrgForScope(`@${orgName}`); } else { org = await this.orgService.findOrgByName(orgName); if (!org) { throw new NotFoundError(`Org "${orgName}" not found`); } } const team = await this.teamRepository.findTeam(org.orgId, teamName); if (!team) { throw new NotFoundError(`Team "${teamName}" not found`); } // Admin always has access if (isAdmin) { return { org, team, authorizedUser }; } // Org owner has access if (!this.isAllowScopeOrg(orgName)) { const orgMember = await this.orgRepository.findMember(org.orgId, authorizedUser.userId); if (orgMember && orgMember.role === 'owner') { return { org, team, authorizedUser }; } } // Team owner has access const teamMember = await this.teamRepository.findMember(team.teamId, authorizedUser.userId); if (teamMember && teamMember.role === 'owner') { return { org, team, authorizedUser }; } throw new ForbiddenError('Only team owner or admin can perform this action'); } // --- Team CRUD --- // npm team create @scope:team → PUT /-/org/:orgName/team async createTeam(ctx, orgName, body) { const { org, authorizedUser } = await this.requireOrgWriteAccess(ctx, orgName); if (!body.name) { throw new UnprocessableEntityError('name is required'); } await this.teamService.createTeam(org.orgId, body.name, body.description, authorizedUser.userId); return { ok: true }; } // npm team ls @scope → GET /-/org/:orgName/team async listTeams(ctx, orgName) { await this.userRoleManager.requiredAuthorizedUser(ctx, 'read'); const org = await this.findOrg(orgName); if (!org) { throw new NotFoundError(`Org "${orgName}" not found`); } const teams = await this.teamRepository.listTeamsByOrgId(org.orgId); // npm CLI adds @ prefix itself, return "scope:teamname" format return teams.map((t) => `${orgName}:${t.name}`); } // GET /-/team/:orgName/:teamName (npm compatible show) async showTeam(ctx, orgName, teamName) { await this.userRoleManager.requiredAuthorizedUser(ctx, 'read'); const org = await this.findOrg(orgName); if (!org) { throw new NotFoundError(`Org "${orgName}" not found`); } const team = await this.teamRepository.findTeam(org.orgId, teamName); if (!team) { throw new NotFoundError(`Team "${teamName}" not found`); } return { name: team.name, description: team.description, created: team.createdAt, }; } // npm team destroy @scope:team → DELETE /-/team/:orgName/:teamName async removeTeam(ctx, orgName, teamName) { const { team } = await this.requireTeamWriteAccess(ctx, orgName, teamName); await this.teamService.removeTeam(team.teamId); return { ok: true }; } // --- Team Members (npm uses "user") --- // npm team ls @scope:team → GET /-/team/:orgName/:teamName/user // npm compatible: returns string array ["user1", "user2"] async listTeamMembers(ctx, orgName, teamName) { await this.userRoleManager.requiredAuthorizedUser(ctx, 'read'); const org = await this.findOrg(orgName); if (!org) { throw new NotFoundError(`Org "${orgName}" not found`); } const team = await this.teamRepository.findTeam(org.orgId, teamName); if (!team) { throw new NotFoundError(`Team "${teamName}" not found`); } const members = await this.teamService.listMembers(team.teamId); const users = await this.userRepository.findUsersByUserIds(members.map((m) => m.userId)); return users.map((u) => u.displayName); } // Private API: GET /-/team/:orgName/:teamName/member // Returns [{user, role}] with team member role info async listTeamMembersWithRole(ctx, orgName, teamName) { await this.userRoleManager.requiredAuthorizedUser(ctx, 'read'); const org = await this.findOrg(orgName); if (!org) { throw new NotFoundError(`Org "${orgName}" not found`); } const team = await this.teamRepository.findTeam(org.orgId, teamName); if (!team) { throw new NotFoundError(`Team "${teamName}" not found`); } const members = await this.teamService.listMembers(team.teamId); const users = await this.userRepository.findUsersByUserIds(members.map((m) => m.userId)); const userMap = new Map(users.map((u) => [u.userId, u])); return members.map((m) => ({ user: userMap.get(m.userId)?.displayName ?? '', role: m.role, })); } // Private API: PATCH /-/team/:orgName/:teamName/member/:username // Update team member role async updateTeamMemberRole(ctx, orgName, teamName, username, body) { const { team } = await this.requireTeamWriteAccess(ctx, orgName, teamName); if (!body.role || (body.role !== 'owner' && body.role !== 'member')) { throw new UnprocessableEntityError('role is required and must be "owner" or "member"'); } const targetUser = await this.userRepository.findUserByName(username); if (!targetUser) { throw new NotFoundError(`User "${username}" not found`); } const member = await this.teamRepository.findMember(team.teamId, targetUser.userId); if (!member) { throw new NotFoundError(`User "${username}" is not a member of this team`); } await this.teamService.addMember(team.teamId, targetUser.userId, body.role); return { ok: true }; } // npm team add <user> @scope:team → PUT /-/team/:orgName/:teamName/user async addTeamMember(ctx, orgName, teamName, body) { const { team } = await this.requireTeamWriteAccess(ctx, orgName, teamName); if (!body.user) { throw new UnprocessableEntityError('user is required'); } const targetUser = await this.userRepository.findUserByName(body.user); if (!targetUser) { throw new NotFoundError(`User "${body.user}" not found`); } await this.teamService.addMember(team.teamId, targetUser.userId); return { ok: true }; } // npm team rm <user> @scope:team → DELETE /-/team/:orgName/:teamName/user body:{user} async removeTeamMember(ctx, orgName, teamName, body) { const { team } = await this.requireTeamWriteAccess(ctx, orgName, teamName); if (!body.user) { throw new UnprocessableEntityError('user is required'); } const targetUser = await this.userRepository.findUserByName(body.user); if (!targetUser) { throw new NotFoundError(`User "${body.user}" not found`); } await this.teamService.removeMember(team.teamId, targetUser.userId); return { ok: true }; } // --- Team Packages --- // npm access ls-packages @scope:team → GET /-/team/:orgName/:teamName/package async listTeamPackages(ctx, orgName, teamName) { await this.userRoleManager.requiredAuthorizedUser(ctx, 'read'); const org = await this.findOrg(orgName); if (!org) { throw new NotFoundError(`Org "${orgName}" not found`); } const team = await this.teamRepository.findTeam(org.orgId, teamName); if (!team) { throw new NotFoundError(`Team "${teamName}" not found`); } const teamPackages = await this.teamService.listPackages(team.teamId); const pkgs = await this.packageRepository.findPackagesByPackageIds(teamPackages.map((tp) => tp.packageId)); const result = {}; for (const pkg of pkgs) { result[pkg.fullname] = 'read'; } return result; } // npm access grant read-only @scope:team <pkg> → PUT /-/team/:orgName/:teamName/package async grantPackageAccess(ctx, orgName, teamName, body) { const { team } = await this.requireTeamWriteAccess(ctx, orgName, teamName); if (!body.package) { throw new UnprocessableEntityError('package is required'); } const [scope, name] = getScopeAndName(body.package); const pkg = await this.packageRepository.findPackage(scope, name); if (!pkg) { throw new NotFoundError(`Package "${body.package}" not found`); } await this.teamService.grantPackageAccess(team.teamId, pkg.packageId); return { ok: true }; } // npm access revoke @scope:team <pkg> → DELETE /-/team/:orgName/:teamName/package body:{package} async revokePackageAccess(ctx, orgName, teamName, body) { const { team } = await this.requireTeamWriteAccess(ctx, orgName, teamName); if (!body.package) { throw new UnprocessableEntityError('package is required'); } const [scope, name] = getScopeAndName(body.package); const pkg = await this.packageRepository.findPackage(scope, name); if (!pkg) { throw new NotFoundError(`Package "${body.package}" not found`); } await this.teamService.revokePackageAccess(team.teamId, pkg.packageId); return { ok: true }; } }; __decorate([ Inject(), __metadata("design:type", Function) ], TeamController.prototype, "orgService", void 0); __decorate([ Inject(), __metadata("design:type", Function) ], TeamController.prototype, "teamService", void 0); __decorate([ Inject(), __metadata("design:type", Function) ], TeamController.prototype, "orgRepository", void 0); __decorate([ Inject(), __metadata("design:type", Function) ], TeamController.prototype, "teamRepository", void 0); __decorate([ HTTPMethod({ path: '/-/org/:orgName/team', method: HTTPMethodEnum.PUT, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPBody()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, Object]), __metadata("design:returntype", Promise) ], TeamController.prototype, "createTeam", null); __decorate([ HTTPMethod({ path: '/-/org/:orgName/team', method: HTTPMethodEnum.GET, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String]), __metadata("design:returntype", Promise) ], TeamController.prototype, "listTeams", null); __decorate([ HTTPMethod({ path: '/-/team/:orgName/:teamName', method: HTTPMethodEnum.GET, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPParam()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, String]), __metadata("design:returntype", Promise) ], TeamController.prototype, "showTeam", null); __decorate([ HTTPMethod({ path: '/-/team/:orgName/:teamName', method: HTTPMethodEnum.DELETE, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPParam()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, String]), __metadata("design:returntype", Promise) ], TeamController.prototype, "removeTeam", null); __decorate([ HTTPMethod({ path: '/-/team/:orgName/:teamName/user', method: HTTPMethodEnum.GET, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPParam()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, String]), __metadata("design:returntype", Promise) ], TeamController.prototype, "listTeamMembers", null); __decorate([ HTTPMethod({ path: '/-/team/:orgName/:teamName/member', method: HTTPMethodEnum.GET, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPParam()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, String]), __metadata("design:returntype", Promise) ], TeamController.prototype, "listTeamMembersWithRole", null); __decorate([ HTTPMethod({ path: '/-/team/:orgName/:teamName/member/:username', method: HTTPMethodEnum.PATCH, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPParam()), __param(3, HTTPParam()), __param(4, HTTPBody()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, String, String, Object]), __metadata("design:returntype", Promise) ], TeamController.prototype, "updateTeamMemberRole", null); __decorate([ HTTPMethod({ path: '/-/team/:orgName/:teamName/user', method: HTTPMethodEnum.PUT, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPParam()), __param(3, HTTPBody()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, String, Object]), __metadata("design:returntype", Promise) ], TeamController.prototype, "addTeamMember", null); __decorate([ HTTPMethod({ path: '/-/team/:orgName/:teamName/user', method: HTTPMethodEnum.DELETE, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPParam()), __param(3, HTTPBody()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, String, Object]), __metadata("design:returntype", Promise) ], TeamController.prototype, "removeTeamMember", null); __decorate([ HTTPMethod({ path: '/-/team/:orgName/:teamName/package', method: HTTPMethodEnum.GET, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPParam()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, String]), __metadata("design:returntype", Promise) ], TeamController.prototype, "listTeamPackages", null); __decorate([ HTTPMethod({ path: '/-/team/:orgName/:teamName/package', method: HTTPMethodEnum.PUT, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPParam()), __param(3, HTTPBody()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, String, Object]), __metadata("design:returntype", Promise) ], TeamController.prototype, "grantPackageAccess", null); __decorate([ HTTPMethod({ path: '/-/team/:orgName/:teamName/package', method: HTTPMethodEnum.DELETE, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPParam()), __param(3, HTTPBody()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, String, Object]), __metadata("design:returntype", Promise) ], TeamController.prototype, "revokePackageAccess", null); TeamController = __decorate([ HTTPController() ], TeamController); export { TeamController }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGVhbUNvbnRyb2xsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9hcHAvcG9ydC9jb250cm9sbGVyL1RlYW1Db250cm9sbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxjQUFjLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBQ3BILE9BQU8sRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFLHdCQUF3QixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRXJGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUs5RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUd0RCxJQUFNLGNBQWMsR0FBcEIsTUFBTSxjQUFlLFNBQVEsa0JBQWtCO0lBYTVDLGVBQWUsQ0FBQyxPQUFlO1FBQ3JDLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUVELDhEQUE4RDtJQUN0RCxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQWU7UUFDbkMsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDbEMsT0FBTyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsaUJBQWlCLENBQUMsSUFBSSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ2hFLENBQUM7UUFDRCxPQUFPLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVPLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxHQUFZLEVBQUUsT0FBZTtRQUMvRCxNQUFNLGNBQWMsR0FBRyxNQUFNLElBQUks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