feat(opsserver,web): replace the Angular UI and REST management layer with a TypedRequest-based ops server and bundled web frontend
This commit is contained in:
@@ -113,7 +113,9 @@ export class AdminAuthApi {
|
||||
});
|
||||
} else if (body.type === 'ldap' && body.ldapConfig) {
|
||||
// Encrypt bind password
|
||||
const encryptedPassword = await cryptoService.encrypt(body.ldapConfig.bindPasswordEncrypted);
|
||||
const encryptedPassword = await cryptoService.encrypt(
|
||||
body.ldapConfig.bindPasswordEncrypted,
|
||||
);
|
||||
|
||||
provider = await AuthProvider.createLdapProvider({
|
||||
name: body.name,
|
||||
@@ -228,7 +230,7 @@ export class AdminAuthApi {
|
||||
!cryptoService.isEncrypted(body.oauthConfig.clientSecretEncrypted)
|
||||
) {
|
||||
newOAuthConfig.clientSecretEncrypted = await cryptoService.encrypt(
|
||||
body.oauthConfig.clientSecretEncrypted
|
||||
body.oauthConfig.clientSecretEncrypted,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -245,7 +247,7 @@ export class AdminAuthApi {
|
||||
!cryptoService.isEncrypted(body.ldapConfig.bindPasswordEncrypted)
|
||||
) {
|
||||
newLdapConfig.bindPasswordEncrypted = await cryptoService.encrypt(
|
||||
body.ldapConfig.bindPasswordEncrypted
|
||||
body.ldapConfig.bindPasswordEncrypted,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,9 @@ export class AuditApi {
|
||||
// Parse query parameters
|
||||
const organizationId = ctx.url.searchParams.get('organizationId') || undefined;
|
||||
const repositoryId = ctx.url.searchParams.get('repositoryId') || undefined;
|
||||
const resourceType = ctx.url.searchParams.get('resourceType') as TAuditResourceType | undefined;
|
||||
const resourceType = ctx.url.searchParams.get('resourceType') as
|
||||
| TAuditResourceType
|
||||
| undefined;
|
||||
const actionsParam = ctx.url.searchParams.get('actions');
|
||||
const actions = actionsParam ? (actionsParam.split(',') as TAuditAction[]) : undefined;
|
||||
const success = ctx.url.searchParams.has('success')
|
||||
@@ -54,7 +56,7 @@ export class AuditApi {
|
||||
// Check if user can manage this org
|
||||
const canManage = await this.permissionService.canManageOrganization(
|
||||
ctx.actor.userId,
|
||||
organizationId
|
||||
organizationId,
|
||||
);
|
||||
if (!canManage) {
|
||||
// User can only see their own actions in this org
|
||||
|
||||
@@ -93,7 +93,7 @@ export class OAuthApi {
|
||||
|
||||
const result = await externalAuthService.handleOAuthCallback(
|
||||
{ code, state },
|
||||
{ ipAddress: ctx.ip, userAgent: ctx.userAgent }
|
||||
{ ipAddress: ctx.ip, userAgent: ctx.userAgent },
|
||||
);
|
||||
|
||||
if (!result.success) {
|
||||
|
||||
@@ -208,7 +208,10 @@ export class OrganizationApi {
|
||||
}
|
||||
|
||||
// Check admin permission using org.id
|
||||
const canManage = await this.permissionService.canManageOrganization(ctx.actor.userId, org.id);
|
||||
const canManage = await this.permissionService.canManageOrganization(
|
||||
ctx.actor.userId,
|
||||
org.id,
|
||||
);
|
||||
if (!canManage) {
|
||||
return { status: 403, body: { error: 'Admin access required' } };
|
||||
}
|
||||
@@ -319,13 +322,13 @@ export class OrganizationApi {
|
||||
addedAt: m.joinedAt,
|
||||
user: user
|
||||
? {
|
||||
username: user.username,
|
||||
displayName: user.displayName,
|
||||
avatarUrl: user.avatarUrl,
|
||||
}
|
||||
username: user.username,
|
||||
displayName: user.displayName,
|
||||
avatarUrl: user.avatarUrl,
|
||||
}
|
||||
: null,
|
||||
};
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
return {
|
||||
@@ -356,7 +359,10 @@ export class OrganizationApi {
|
||||
}
|
||||
|
||||
// Check admin permission
|
||||
const canManage = await this.permissionService.canManageOrganization(ctx.actor.userId, org.id);
|
||||
const canManage = await this.permissionService.canManageOrganization(
|
||||
ctx.actor.userId,
|
||||
org.id,
|
||||
);
|
||||
if (!canManage) {
|
||||
return { status: 403, body: { error: 'Admin access required' } };
|
||||
}
|
||||
@@ -431,7 +437,10 @@ export class OrganizationApi {
|
||||
}
|
||||
|
||||
// Check admin permission
|
||||
const canManage = await this.permissionService.canManageOrganization(ctx.actor.userId, org.id);
|
||||
const canManage = await this.permissionService.canManageOrganization(
|
||||
ctx.actor.userId,
|
||||
org.id,
|
||||
);
|
||||
if (!canManage) {
|
||||
return { status: 403, body: { error: 'Admin access required' } };
|
||||
}
|
||||
@@ -492,7 +501,10 @@ export class OrganizationApi {
|
||||
|
||||
// Users can remove themselves, admins can remove others
|
||||
if (userId !== ctx.actor.userId) {
|
||||
const canManage = await this.permissionService.canManageOrganization(ctx.actor.userId, org.id);
|
||||
const canManage = await this.permissionService.canManageOrganization(
|
||||
ctx.actor.userId,
|
||||
org.id,
|
||||
);
|
||||
if (!canManage) {
|
||||
return { status: 403, body: { error: 'Admin access required' } };
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ export class PackageApi {
|
||||
ctx.actor.userId,
|
||||
pkg.organizationId,
|
||||
pkg.repositoryId,
|
||||
'read'
|
||||
'read',
|
||||
);
|
||||
if (canAccess) {
|
||||
accessiblePackages.push(pkg);
|
||||
@@ -106,7 +106,7 @@ export class PackageApi {
|
||||
ctx.actor.userId,
|
||||
pkg.organizationId,
|
||||
pkg.repositoryId,
|
||||
'read'
|
||||
'read',
|
||||
);
|
||||
|
||||
if (!canAccess) {
|
||||
@@ -161,7 +161,7 @@ export class PackageApi {
|
||||
ctx.actor.userId,
|
||||
pkg.organizationId,
|
||||
pkg.repositoryId,
|
||||
'read'
|
||||
'read',
|
||||
);
|
||||
|
||||
if (!canAccess) {
|
||||
@@ -213,7 +213,7 @@ export class PackageApi {
|
||||
ctx.actor.userId,
|
||||
pkg.organizationId,
|
||||
pkg.repositoryId,
|
||||
'delete'
|
||||
'delete',
|
||||
);
|
||||
|
||||
if (!canDelete) {
|
||||
@@ -267,7 +267,7 @@ export class PackageApi {
|
||||
ctx.actor.userId,
|
||||
pkg.organizationId,
|
||||
pkg.repositoryId,
|
||||
'delete'
|
||||
'delete',
|
||||
);
|
||||
|
||||
if (!canDelete) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import type { IApiContext, IApiResponse } from '../router.ts';
|
||||
import { PermissionService } from '../../services/permission.service.ts';
|
||||
import { AuditService } from '../../services/audit.service.ts';
|
||||
import { Repository, Organization } from '../../models/index.ts';
|
||||
import { Organization, Repository } from '../../models/index.ts';
|
||||
import type { TRegistryProtocol, TRepositoryVisibility } from '../../interfaces/auth.interfaces.ts';
|
||||
|
||||
export class RepositoryApi {
|
||||
@@ -28,7 +28,7 @@ export class RepositoryApi {
|
||||
try {
|
||||
const repositories = await this.permissionService.getAccessibleRepositories(
|
||||
ctx.actor.userId,
|
||||
orgId
|
||||
orgId,
|
||||
);
|
||||
|
||||
return {
|
||||
@@ -131,7 +131,10 @@ export class RepositoryApi {
|
||||
if (!/^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$/.test(name)) {
|
||||
return {
|
||||
status: 400,
|
||||
body: { error: 'Name must be lowercase alphanumeric with optional dots, hyphens, or underscores' },
|
||||
body: {
|
||||
error:
|
||||
'Name must be lowercase alphanumeric with optional dots, hyphens, or underscores',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -198,7 +201,7 @@ export class RepositoryApi {
|
||||
const canManage = await this.permissionService.canManageRepository(
|
||||
ctx.actor.userId,
|
||||
repo.organizationId,
|
||||
id
|
||||
id,
|
||||
);
|
||||
if (!canManage) {
|
||||
return { status: 403, body: { error: 'Admin access required' } };
|
||||
@@ -252,7 +255,7 @@ export class RepositoryApi {
|
||||
const canManage = await this.permissionService.canManageRepository(
|
||||
ctx.actor.userId,
|
||||
repo.organizationId,
|
||||
id
|
||||
id,
|
||||
);
|
||||
if (!canManage) {
|
||||
return { status: 403, body: { error: 'Admin access required' } };
|
||||
|
||||
@@ -33,7 +33,10 @@ export class TokenApi {
|
||||
let tokens;
|
||||
if (organizationId) {
|
||||
// Check if user can manage org
|
||||
const canManage = await this.permissionService.canManageOrganization(ctx.actor.userId, organizationId);
|
||||
const canManage = await this.permissionService.canManageOrganization(
|
||||
ctx.actor.userId,
|
||||
organizationId,
|
||||
);
|
||||
if (!canManage) {
|
||||
return { status: 403, body: { error: 'Not authorized to view organization tokens' } };
|
||||
}
|
||||
@@ -119,7 +122,10 @@ export class TokenApi {
|
||||
|
||||
// If creating org token, verify permission
|
||||
if (organizationId) {
|
||||
const canManage = await this.permissionService.canManageOrganization(ctx.actor.userId, organizationId);
|
||||
const canManage = await this.permissionService.canManageOrganization(
|
||||
ctx.actor.userId,
|
||||
organizationId,
|
||||
);
|
||||
if (!canManage) {
|
||||
return { status: 403, body: { error: 'Not authorized to create organization tokens' } };
|
||||
}
|
||||
@@ -181,7 +187,7 @@ export class TokenApi {
|
||||
if (anyToken?.organizationId) {
|
||||
const canManage = await this.permissionService.canManageOrganization(
|
||||
ctx.actor.userId,
|
||||
anyToken.organizationId
|
||||
anyToken.organizationId,
|
||||
);
|
||||
if (canManage) {
|
||||
token = anyToken;
|
||||
|
||||
Reference in New Issue
Block a user