feat(api): Implement Console Export Client and Models
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (push) Has been cancelled
Findings Ledger CI / generate-manifest (push) Has been cancelled
mock-dev-release / package-mock-release (push) Has been cancelled
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (push) Has been cancelled
Findings Ledger CI / generate-manifest (push) Has been cancelled
mock-dev-release / package-mock-release (push) Has been cancelled
- Added ConsoleExportClient for managing export requests and responses. - Introduced ConsoleExportRequest and ConsoleExportResponse models. - Implemented methods for creating and retrieving exports with appropriate headers. feat(crypto): Add Software SM2/SM3 Cryptography Provider - Implemented SmSoftCryptoProvider for software-only SM2/SM3 cryptography. - Added support for signing and verification using SM2 algorithm. - Included hashing functionality with SM3 algorithm. - Configured options for loading keys from files and environment gate checks. test(crypto): Add unit tests for SmSoftCryptoProvider - Created comprehensive tests for signing, verifying, and hashing functionalities. - Ensured correct behavior for key management and error handling. feat(api): Enhance Console Export Models - Expanded ConsoleExport models to include detailed status and event types. - Added support for various export formats and notification options. test(time): Implement TimeAnchorPolicyService tests - Developed tests for TimeAnchorPolicyService to validate time anchors. - Covered scenarios for anchor validation, drift calculation, and policy enforcement.
This commit is contained in:
120
src/app/core/api/console-export.client.ts
Normal file
120
src/app/core/api/console-export.client.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { AuthSessionStore } from '../auth/auth-session.store';
|
||||
import {
|
||||
CONSOLE_API_BASE_URL,
|
||||
DEFAULT_EVENT_SOURCE_FACTORY,
|
||||
EVENT_SOURCE_FACTORY,
|
||||
EventSourceFactory,
|
||||
} from './console-status.client';
|
||||
import {
|
||||
ConsoleExportEvent,
|
||||
ConsoleExportRequest,
|
||||
ConsoleExportStatusDto,
|
||||
} from './console-export.models';
|
||||
import { generateTraceId } from './trace.util';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ConsoleExportClient {
|
||||
constructor(
|
||||
private readonly http: HttpClient,
|
||||
private readonly authSession: AuthSessionStore,
|
||||
@Inject(CONSOLE_API_BASE_URL) private readonly baseUrl: string,
|
||||
@Inject(EVENT_SOURCE_FACTORY)
|
||||
private readonly eventSourceFactory: EventSourceFactory = DEFAULT_EVENT_SOURCE_FACTORY
|
||||
) {}
|
||||
|
||||
createExport(
|
||||
request: ConsoleExportRequest,
|
||||
options?: { tenantId?: string; traceId?: string; idempotencyKey?: string }
|
||||
): Observable<ConsoleExportStatusDto> {
|
||||
const trace = options?.traceId ?? generateTraceId();
|
||||
const tenant = this.resolveTenant(options?.tenantId);
|
||||
const headers = new HttpHeaders({
|
||||
'X-StellaOps-Tenant': tenant,
|
||||
'X-Stella-Trace-Id': trace,
|
||||
'X-Stella-Request-Id': trace,
|
||||
...(options?.idempotencyKey
|
||||
? { 'Idempotency-Key': options.idempotencyKey }
|
||||
: undefined),
|
||||
});
|
||||
|
||||
return this.http
|
||||
.post<ConsoleExportStatusDto>(`${this.baseUrl}/exports`, request, { headers })
|
||||
.pipe(map(this.normalizeStatus));
|
||||
}
|
||||
|
||||
getExport(
|
||||
exportId: string,
|
||||
options?: { tenantId?: string; traceId?: string }
|
||||
): Observable<ConsoleExportStatusDto> {
|
||||
const trace = options?.traceId ?? generateTraceId();
|
||||
const tenant = this.resolveTenant(options?.tenantId);
|
||||
const headers = new HttpHeaders({
|
||||
'X-StellaOps-Tenant': tenant,
|
||||
'X-Stella-Trace-Id': trace,
|
||||
'X-Stella-Request-Id': trace,
|
||||
});
|
||||
|
||||
return this.http
|
||||
.get<ConsoleExportStatusDto>(`${this.baseUrl}/exports/${encodeURIComponent(exportId)}`, {
|
||||
headers,
|
||||
})
|
||||
.pipe(map(this.normalizeStatus));
|
||||
}
|
||||
|
||||
streamExport(
|
||||
exportId: string,
|
||||
options?: { tenantId?: string; traceId?: string }
|
||||
): Observable<ConsoleExportEvent> {
|
||||
const trace = options?.traceId ?? generateTraceId();
|
||||
const tenant = this.resolveTenant(options?.tenantId);
|
||||
const url = `${this.baseUrl}/exports/${encodeURIComponent(
|
||||
exportId
|
||||
)}/events?tenant=${encodeURIComponent(tenant)}&traceId=${encodeURIComponent(trace)}`;
|
||||
|
||||
return new Observable<ConsoleExportEvent>((observer) => {
|
||||
const source = this.eventSourceFactory(url);
|
||||
|
||||
source.onmessage = (event) => {
|
||||
try {
|
||||
const parsed = JSON.parse(event.data) as ConsoleExportEvent;
|
||||
observer.next(parsed);
|
||||
} catch (err) {
|
||||
observer.error(err);
|
||||
}
|
||||
};
|
||||
|
||||
source.onerror = (err) => {
|
||||
observer.error(err);
|
||||
source.close();
|
||||
};
|
||||
|
||||
return () => source.close();
|
||||
});
|
||||
}
|
||||
|
||||
private resolveTenant(tenantId?: string): string {
|
||||
const tenant = (tenantId && tenantId.trim()) || this.authSession.getActiveTenantId();
|
||||
if (!tenant) {
|
||||
throw new Error('ConsoleExportClient requires an active tenant identifier.');
|
||||
}
|
||||
return tenant;
|
||||
}
|
||||
|
||||
private readonly normalizeStatus = (dto: ConsoleExportStatusDto): ConsoleExportStatusDto => ({
|
||||
...dto,
|
||||
estimateSeconds: dto.estimateSeconds ?? null,
|
||||
retryAfter: dto.retryAfter ?? null,
|
||||
createdAt: dto.createdAt ?? null,
|
||||
updatedAt: dto.updatedAt ?? null,
|
||||
outputs: dto.outputs ?? [],
|
||||
progress: dto.progress ?? null,
|
||||
errors: dto.errors ?? [],
|
||||
});
|
||||
}
|
||||
96
src/app/core/api/console-export.models.ts
Normal file
96
src/app/core/api/console-export.models.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
export type ConsoleExportStatus =
|
||||
| 'queued'
|
||||
| 'running'
|
||||
| 'succeeded'
|
||||
| 'failed'
|
||||
| 'expired';
|
||||
|
||||
export type ConsoleExportFormat = 'json' | 'csv' | 'ndjson' | 'pdf';
|
||||
|
||||
export interface ConsoleExportScope {
|
||||
readonly tenantId: string;
|
||||
readonly projectId?: string | null;
|
||||
}
|
||||
|
||||
export type ConsoleExportSourceType = 'advisory' | 'vex' | 'policy' | 'scan';
|
||||
|
||||
export interface ConsoleExportSource {
|
||||
readonly type: ConsoleExportSourceType;
|
||||
readonly ids: readonly string[];
|
||||
}
|
||||
|
||||
export interface ConsoleExportAttestations {
|
||||
readonly include: boolean;
|
||||
readonly sigstoreBundle?: boolean;
|
||||
}
|
||||
|
||||
export interface ConsoleExportNotify {
|
||||
readonly webhooks?: readonly string[];
|
||||
readonly email?: readonly string[];
|
||||
}
|
||||
|
||||
export type ConsoleExportPriority = 'low' | 'normal' | 'high';
|
||||
|
||||
export interface ConsoleExportRequest {
|
||||
readonly scope: ConsoleExportScope;
|
||||
readonly sources: readonly ConsoleExportSource[];
|
||||
readonly formats: readonly ConsoleExportFormat[];
|
||||
readonly attestations?: ConsoleExportAttestations;
|
||||
readonly notify?: ConsoleExportNotify;
|
||||
readonly priority?: ConsoleExportPriority;
|
||||
}
|
||||
|
||||
export interface ConsoleExportOutput {
|
||||
readonly type: string;
|
||||
readonly format: ConsoleExportFormat | string;
|
||||
readonly url: string;
|
||||
readonly sha256?: string;
|
||||
readonly expiresAt?: string | null;
|
||||
}
|
||||
|
||||
export interface ConsoleExportProgress {
|
||||
readonly percent: number;
|
||||
readonly itemsCompleted?: number;
|
||||
readonly itemsTotal?: number;
|
||||
readonly assetsReady?: number;
|
||||
}
|
||||
|
||||
export interface ConsoleExportError {
|
||||
readonly code: string;
|
||||
readonly message: string;
|
||||
}
|
||||
|
||||
export interface ConsoleExportStatusDto {
|
||||
readonly exportId: string;
|
||||
readonly status: ConsoleExportStatus;
|
||||
readonly estimateSeconds?: number | null;
|
||||
readonly retryAfter?: number | null;
|
||||
readonly createdAt?: string | null;
|
||||
readonly updatedAt?: string | null;
|
||||
readonly outputs?: readonly ConsoleExportOutput[];
|
||||
readonly progress?: ConsoleExportProgress | null;
|
||||
readonly errors?: readonly ConsoleExportError[];
|
||||
}
|
||||
|
||||
export type ConsoleExportEventType =
|
||||
| 'started'
|
||||
| 'progress'
|
||||
| 'asset_ready'
|
||||
| 'completed'
|
||||
| 'failed';
|
||||
|
||||
export interface ConsoleExportEvent {
|
||||
readonly event: ConsoleExportEventType;
|
||||
readonly exportId: string;
|
||||
readonly percent?: number;
|
||||
readonly itemsCompleted?: number;
|
||||
readonly itemsTotal?: number;
|
||||
readonly type?: string;
|
||||
readonly id?: string;
|
||||
readonly url?: string;
|
||||
readonly sha256?: string;
|
||||
readonly status?: ConsoleExportStatus;
|
||||
readonly manifestUrl?: string;
|
||||
readonly code?: string;
|
||||
readonly message?: string;
|
||||
}
|
||||
Reference in New Issue
Block a user