diff --git a/src/Client/src/app/pages/company/editor/editor.component.html b/src/Client/src/app/pages/company/editor/editor.component.html
index 8b85075..04eda5b 100644
--- a/src/Client/src/app/pages/company/editor/editor.component.html
+++ b/src/Client/src/app/pages/company/editor/editor.component.html
@@ -22,7 +22,7 @@
Public:
Is Veteran:
-
@@ -140,7 +139,7 @@
@@ -156,7 +155,7 @@
diff --git a/src/Client/src/app/pages/resumes/editor/editor.component.ts b/src/Client/src/app/pages/resumes/editor/editor.component.ts
index f4c8ee9..4536848 100644
--- a/src/Client/src/app/pages/resumes/editor/editor.component.ts
+++ b/src/Client/src/app/pages/resumes/editor/editor.component.ts
@@ -90,32 +90,22 @@ export class ResumesEditorComponent {
validatePhone(input: string){
let result = this.validator.validatePhoneNumber(input);
- if (result[0]){
- this.resume.phoneNumber = result[1];
- }
+ this.resume.phoneNumber = result[1];
}
validateEmail(input: string){
let result = this.validator.validateEmail(input);
- if (result[0]){
- this.resume.email = result[1];
- }
+ this.resume.email = result[1];
}
- PrintResume(){
- const divToPrint = document.getElementsByClassName("paper")[0];
+ validateCertURL(input: ResumeCertification){
+ let result = this.validator.validateURL(input.verificationURL);
+ input.verificationURL = result[1];
+ }
- const printContents = divToPrint.innerHTML;
- const originalContents = document.body.innerHTML; // Store original body content
-
- // Temporarily replace the body content with the div's content
- document.body.innerHTML = printContents;
-
- // Trigger the print dialog
- window.print();
-
- // Restore the original body content
- document.body.innerHTML = originalContents;
+ validateProjectURL(input: ResumeProject){
+ let result = this.validator.validateURL(input.url);
+ input.url = result[1];
}
addExperience(){
diff --git a/src/Client/src/app/services/Validation.ts b/src/Client/src/app/services/Validation.ts
index 56314ea..ef7c99a 100644
--- a/src/Client/src/app/services/Validation.ts
+++ b/src/Client/src/app/services/Validation.ts
@@ -25,11 +25,65 @@ export class Validation {
}
}
- emailRegex: RegExp = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
+ emailRegex: RegExp = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
validateEmail(input: string): [boolean, string] {
- const corrected = input.trim().toLowerCase();
+ const trimmed = input.trim();
+ const [local, domain] = trimmed.split('@');
+ const corrected = domain ? `${local}@${domain.toLowerCase()}` : trimmed;
+
+ // Extra checks to avoid invalid formats
+ if ( corrected.includes('..') || corrected.startsWith('.') || corrected.endsWith('.') ) {
+ return [false, corrected];
+ }
+
const success = this.emailRegex.test(corrected);
return [success, corrected];
}
+ validateURL(input: string): [boolean, string] {
+ const testUrl = /^https?:\/\//i.test(input) ? input : "http://" + input;
+ var urlToParse = new URL(testUrl);
+ try {
+
+ if (urlToParse.protocol !== 'http:' && urlToParse.protocol !== 'https:') {
+ return [false, urlToParse.href];
+ }
+
+ const hostname = urlToParse.hostname.toLowerCase();
+ if (hostname === 'localhost' || hostname.endsWith('.localhost')) {
+ return [false, urlToParse.href];
+ }
+
+ const privateIpRegex = /^(127\.|10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)/;
+ if (privateIpRegex.test(hostname)) {
+ return [false, urlToParse.href];
+ }
+
+ if (hostname.includes(':')) {
+ if (this.isPrivateIPv6(hostname)) {
+ return [false, urlToParse.href];
+ }
+ }
+
+ return [true, urlToParse.href.substring(0, urlToParse.href.length - 1)];
+ } catch (e) {
+ return [false, urlToParse.href];
+ }
+ }
+
+ ///////// HELPER FUNCTIONS /////////
+
+ isPrivateIPv6(ip: string): boolean {
+ try {
+ const normalized = ip.replace(/^\[|\]$/g, '').toLowerCase();
+ if (normalized === '::1') return true;
+ if (normalized.startsWith('fc') || normalized.startsWith('fd')) return true;
+ const first4 = normalized.slice(0, 4);
+ if (first4 >= 'fe80' && first4 <= 'febf') return true;
+ return false;
+ } catch {
+ return true;
+ }
+}
+
}
\ No newline at end of file