Skip to content

Commit

Permalink
Handle feedbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
ndkhanh-axonivy committed Dec 16, 2024
1 parent ebfff4f commit c2b4431
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,21 @@

import com.axonivy.market.bo.Artifact;
import com.axonivy.market.constants.CommonConstants;
import com.axonivy.market.constants.GitHubConstants;
import com.axonivy.market.github.model.CodeScanning;
import com.axonivy.market.github.model.Dependabot;
import com.axonivy.market.github.model.SecretScanning;
import com.axonivy.market.util.MavenUtils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.kohsuke.github.GHCommit;
import org.kohsuke.github.GHContent;
import org.kohsuke.github.GHOrganization;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.PagedIterable;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import static com.axonivy.market.constants.MetaConstants.META_FILE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { HttpErrorResponse } from '@angular/common/http';

import { SecurityMonitorService } from './security-monitor.service';
import { ProductSecurityInfo } from '../../shared/models/product-security-info-model';
import { GITHUB_MARKET_ORG_URL, UNAUTHORIZED } from '../../shared/constants/common.constant';
import { GITHUB_MARKET_ORG_URL, REPO_PAGE_PATHS, SECURITY_MONITOR_MESSAGES, SECURITY_MONITOR_SESSION_KEYS, TIME_UNITS, UNAUTHORIZED } from '../../shared/constants/common.constant';

@Component({
selector: 'app-security-monitor',
Expand All @@ -22,17 +22,13 @@ export class SecurityMonitorComponent {
repos: ProductSecurityInfo[] = [];

private readonly securityMonitorService = inject(SecurityMonitorService);
private readonly sessionKeys = {
data: 'security-monitor-data',
token: 'security-monitor-token',
};

ngOnInit(): void {
this.loadSessionData();
}

onSubmit(): void {
this.token = this.token ?? sessionStorage.getItem(this.sessionKeys.token) ?? '';
this.token = this.token ?? sessionStorage.getItem(SECURITY_MONITOR_SESSION_KEYS.TOKEN) ?? '';
if (!this.token) {
this.handleMissingToken();
return;
Expand All @@ -43,7 +39,7 @@ export class SecurityMonitorComponent {
}

private loadSessionData(): void {
const sessionData = sessionStorage.getItem(this.sessionKeys.data);
const sessionData = sessionStorage.getItem(SECURITY_MONITOR_SESSION_KEYS.DATA);
if (sessionData) {
try {
this.repos = JSON.parse(sessionData) as ProductSecurityInfo[];
Expand All @@ -55,7 +51,7 @@ export class SecurityMonitorComponent {
}

private handleMissingToken(): void {
this.errorMessage = 'Token is required';
this.errorMessage = SECURITY_MONITOR_MESSAGES.TOKEN_REQUIRED;
this.isAuthenticated = false;
this.clearSessionData();
}
Expand All @@ -70,24 +66,22 @@ export class SecurityMonitorComponent {
private handleSuccess(data: ProductSecurityInfo[]): void {
this.repos = data;
this.isAuthenticated = true;
sessionStorage.setItem(this.sessionKeys.token, this.token);
sessionStorage.setItem(this.sessionKeys.data, JSON.stringify(data));
sessionStorage.setItem(SECURITY_MONITOR_SESSION_KEYS.TOKEN, this.token);
sessionStorage.setItem(SECURITY_MONITOR_SESSION_KEYS.DATA, JSON.stringify(data));
}

private handleError(err: HttpErrorResponse): void {
if (err.status === UNAUTHORIZED ) {
this.errorMessage = 'Unauthorized access.';
}
else {
this.errorMessage = 'Failed to fetch security data. Check logs for details.';
}
this.errorMessage = err.status === UNAUTHORIZED
? SECURITY_MONITOR_MESSAGES.UNAUTHORIZED_ACCESS
: SECURITY_MONITOR_MESSAGES.FETCH_FAILURE;

this.isAuthenticated = false;
this.clearSessionData();
}

private clearSessionData(): void {
sessionStorage.removeItem(this.sessionKeys.token);
sessionStorage.removeItem(this.sessionKeys.data);
sessionStorage.removeItem(SECURITY_MONITOR_SESSION_KEYS.TOKEN);
sessionStorage.removeItem(SECURITY_MONITOR_SESSION_KEYS.DATA);
}

hasAlerts(alerts: Record<string, number>): boolean {
Expand All @@ -103,19 +97,10 @@ export class SecurityMonitorComponent {
window.open(url, '_blank');
}

navigateToRepoPage(repoName: string, page: RepoPage, lastCommitSHA?: string): void {
const paths: Record<RepoPage, string> = {
security: '/security',
dependabot: '/security/dependabot',
codeScanning: '/security/code-scanning',
secretScanning: '/security/secret-scanning',
branches: '/settings/branches',
lastCommit: `/commit/${lastCommitSHA ?? ''}`,
};

const path = paths[page];
navigateToRepoPage(repoName: string, page: keyof typeof REPO_PAGE_PATHS, lastCommitSHA?: string): void {
const path = REPO_PAGE_PATHS[page];
if (path) {
this.navigateToPage(repoName, path);
this.navigateToPage(repoName, path, page === 'lastCommit' ? lastCommitSHA ?? '' : '');
}
}

Expand All @@ -124,44 +109,18 @@ export class SecurityMonitorComponent {
const targetDate = new Date(date).getTime();
const diffInSeconds = Math.floor((now - targetDate) / 1000);

const timeUnits = [
{ seconds: 60, singular: 'minute', plural: 'minutes' },
{ seconds: 3600, singular: 'hour', plural: 'hours' },
{ seconds: 86400, singular: 'day', plural: 'days' },
{ seconds: 604800, singular: 'week', plural: 'weeks' },
{ seconds: 2592000, singular: 'month', plural: 'months' },
{ seconds: 31536000, singular: 'year', plural: 'years' },
];

if (diffInSeconds < 60) {
return 'just now';
}

for (const { seconds, singular: unitSingular, plural: unitPlural } of timeUnits) {
if (diffInSeconds < seconds) {
const value = Math.floor(diffInSeconds / (seconds / 60));
if (value === 1) {
return `${value} ${unitSingular} ago`;
} else {
return `${value} ${unitPlural} ago`;
}

for (const { SECONDS, SINGULAR, PLURAL } of TIME_UNITS) {
if (diffInSeconds < SECONDS) {
const value = Math.floor(diffInSeconds / (SECONDS / 60));
return value === 1 ? `${value} ${SINGULAR} ago` : `${value} ${PLURAL} ago`;
}
}

const lastUnit = timeUnits[timeUnits.length - 1];
const years = Math.floor(diffInSeconds / lastUnit.seconds);
if (years === 1) {
return `${years} ${lastUnit.singular} ago`;
} else {
return `${years} ${lastUnit.plural} ago`;
}

const years = Math.floor(diffInSeconds / TIME_UNITS[TIME_UNITS.length - 1].SECONDS);
return years === 1 ? `${years} year ago` : `${years} years ago`;
}
}

type RepoPage =
| 'security'
| 'dependabot'
| 'codeScanning'
| 'secretScanning'
| 'branches'
| 'lastCommit';
31 changes: 30 additions & 1 deletion marketplace-ui/src/app/shared/constants/common.constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,4 +248,33 @@ export const DAYS_IN_A_WEEK = 7;
export const DAYS_IN_A_MONTH = 30;
export const DAYS_IN_A_YEAR = 365;

export const MAX_FEEDBACK_LENGTH =250;
export const MAX_FEEDBACK_LENGTH =250;

export const SECURITY_MONITOR_SESSION_KEYS = {
DATA: 'security-monitor-data',
TOKEN: 'security-monitor-token',
};

export const SECURITY_MONITOR_MESSAGES = {
TOKEN_REQUIRED: 'Token is required',
UNAUTHORIZED_ACCESS: 'Unauthorized access.',
FETCH_FAILURE: 'Failed to fetch security data. Check logs for details.',
};

export const TIME_UNITS = [
{ SECONDS: 60, SINGULAR: 'minute', PLURAL: 'minutes' },
{ SECONDS: 3600, SINGULAR: 'hour', PLURAL: 'hours' },
{ SECONDS: 86400, SINGULAR: 'day', PLURAL: 'days' },
{ SECONDS: 604800, SINGULAR: 'week', PLURAL: 'weeks' },
{ SECONDS: 2592000, SINGULAR: 'month', PLURAL: 'months' },
{ SECONDS: 31536000, SINGULAR: 'year', PLURAL: 'years' },
];

export const REPO_PAGE_PATHS: Record<string, string> = {
security: '/security',
dependabot: '/security/dependabot',
codeScanning: '/security/code-scanning',
secretScanning: '/security/secret-scanning',
branches: '/settings/branches',
lastCommit: '/commit/',
};

0 comments on commit c2b4431

Please sign in to comment.