cnpmcore
Version:
Private NPM Registry for Enterprise
422 lines • 36 kB
JavaScript
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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