From e99a354888b20985b15713f5e54a373fadd4c73a Mon Sep 17 00:00:00 2001 From: RITANKAR SAHA Date: Thu, 31 Oct 2024 13:31:28 +0530 Subject: [PATCH 01/12] fixed the async errors --- .../controllers/contributorController.js | 57 ++++++++++--------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/webiu-server/controllers/contributorController.js b/webiu-server/controllers/contributorController.js index 5f761d3d..c6b91bb8 100644 --- a/webiu-server/controllers/contributorController.js +++ b/webiu-server/controllers/contributorController.js @@ -18,36 +18,39 @@ const getAllContributors = async (req, res) => { await Promise.all( repositories.map(async (repo) => { - const contributors = await fetchContributors(orgName, repo.name); - - if (!contributors) { - return; + try { + const contributors = await fetchContributors(orgName, repo.name); + if (!contributors) return; + + await Promise.all( + contributors.map(async (contributor) => { + try { + const userDetails = await fetchUserDetails(contributor.login); + if (!userDetails) return; + + if (finalResponse[userDetails.login]) { + finalResponse[userDetails.login].repos.push(repo.name); + } else { + finalResponse[userDetails.login] = { + login: userDetails.login, + contributions: contributor.contributions, + repos: [repo.name], + followers: userDetails.followers, + following: userDetails.following, + avatar_url: userDetails.avatar_url, + }; + } + } catch (err) { + console.error('Error in fetching user details:', err); + } + }) + ); + } catch (err) { + console.error('Error in fetching contributors:', err); } - - await Promise.all( - contributors.map(async (contributor) => { - const userDetails = await fetchUserDetails(contributor.login); - - if (!userDetails) { - return; - } - - if (finalResponse[userDetails.login]) { - finalResponse[userDetails.login].repos.push(repo.name); - } else { - finalResponse[userDetails.login] = { - login: userDetails.login, - contributions: contributor.contributions, - repos: [repo.name], - followers: userDetails.followers, - following: userDetails.following, - avatar_url: userDetails.avatar_url - }; - } - }) - ); }) ); + let allContributors = [] for (const contributor in finalResponse){ allContributors.push(finalResponse[contributor]); From 50d2105b9d56c89294e07be504584463375b1f47 Mon Sep 17 00:00:00 2001 From: RITANKAR SAHA Date: Thu, 31 Oct 2024 13:36:49 +0530 Subject: [PATCH 02/12] fixed redundancy --- webiu-server/controllers/contributorController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webiu-server/controllers/contributorController.js b/webiu-server/controllers/contributorController.js index c6b91bb8..26716bc2 100644 --- a/webiu-server/controllers/contributorController.js +++ b/webiu-server/controllers/contributorController.js @@ -111,6 +111,6 @@ async function fetchUserDetails(username) { } } -module.exports = module.exports = { +module.exports = { getAllContributors, };; From fc5236e678c533cf7eb4c5d1972d9df2780e0e1c Mon Sep 17 00:00:00 2001 From: RITANKAR SAHA Date: Sun, 3 Nov 2024 01:18:14 +0530 Subject: [PATCH 03/12] Modifications made according to the points mentioned in the issue #92 --- .../contributors/contributors.component.ts | 97 +++++++------------ 1 file changed, 36 insertions(+), 61 deletions(-) diff --git a/webiu-ui/src/app/page/contributors/contributors.component.ts b/webiu-ui/src/app/page/contributors/contributors.component.ts index 17ca6de5..8b29d66c 100644 --- a/webiu-ui/src/app/page/contributors/contributors.component.ts +++ b/webiu-ui/src/app/page/contributors/contributors.component.ts @@ -7,6 +7,8 @@ import { ProfileCardComponent } from '../../components/profile-card/profile-card import { HttpClientModule, HttpClient } from '@angular/common/http'; import { CommmonUtilService } from '../../common/service/commmon-util.service'; import { environment } from '../../../environments/environment'; +import { distinctUntilChanged } from 'rxjs/operators'; + @Component({ selector: 'app-contributors', standalone: true, @@ -18,11 +20,11 @@ import { environment } from '../../../environments/environment'; ProfileCardComponent, ], templateUrl: './contributors.component.html', - styleUrl: './contributors.component.scss', + styleUrls: ['./contributors.component.scss'], }) export class ContributorsComponent implements OnInit { - profiles?: Contributor[]; - displayProfiles?: Contributor[]; + profiles: Contributor[] = []; + displayProfiles: Contributor[] = []; searchText = new FormControl(''); selectedRepo: string = ''; allRepos: string[] = []; @@ -39,55 +41,32 @@ export class ContributorsComponent implements OnInit { ngOnInit() { this.getProfiles(); - - this.searchText.valueChanges.subscribe(() => { - this.filterProfiles(); - }); + + this.searchText.valueChanges.pipe(distinctUntilChanged()).subscribe(() => { + this.filterProfiles(); + }); } getProfiles() { this.http - .get(`${environment.serverUrl}/api/contributor/contributors`) + .get(`${environment.serverUrl}/api/contributor/contributors`) .subscribe({ - next: (res) => { - if (res) { - this.profiles = res; - this.commonUtil.commonProfiles = this.profiles; - this.allRepos = this.getUniqueRepos(); - this.totalPages = Math.ceil( - (this.profiles?.length || 0) / this.profilesPerPage - ); - this.filterProfiles(); - this.isLoading = false; - } else { - this.profiles = contributors.flatMap((profile: any) => profile); - this.allRepos = this.getUniqueRepos(); - this.totalPages = Math.ceil( - (this.profiles?.length || 0) / this.profilesPerPage - ); - this.filterProfiles(); - this.isLoading = false; - } - }, - error: (error) => { - this.profiles = contributors.map((profile) => profile); - this.allRepos = this.getUniqueRepos(); - this.totalPages = Math.ceil( - (this.profiles?.length || 0) / this.profilesPerPage - ); - this.filterProfiles(); - this.isLoading = false; - }, + next: (res) => this.handleProfileResponse(res || contributors), + error: () => this.handleProfileResponse(contributors), }); } + handleProfileResponse(profiles: Contributor[]) { + this.profiles = profiles; + this.commonUtil.commonProfiles = this.profiles; + this.allRepos = this.getUniqueRepos(); + this.totalPages = Math.ceil((this.profiles.length || 0) / this.profilesPerPage); + this.filterProfiles(); + this.isLoading = false; + } + getUniqueRepos(): string[] { - let array: string[] = []; - if (this.profiles?.length) { - const repos = this.profiles.flatMap((profile) => profile.repos); - array = Array.from(new Set(repos)); - } - return array; + return Array.from(new Set(this.profiles.flatMap((profile) => profile.repos))); } onRepoChange(event: Event) { @@ -97,30 +76,26 @@ export class ContributorsComponent implements OnInit { } filterProfiles() { - let searchTextValue: string = - this.searchText.value?.toLocaleLowerCase().trim() || ''; - let filteredProfiles = this.profiles?.filter((doc) => { - return ( - (searchTextValue?.length - ? [doc.login].some((str) => - str.toLocaleLowerCase().includes(searchTextValue) - ) - : true) && - (this.selectedRepo?.length - ? doc.repos.includes(this.selectedRepo) - : true) - ); - }); - - this.totalPages = Math.ceil( - (filteredProfiles?.length || 0) / this.profilesPerPage + const searchTextValue = this.searchText.value?.toLocaleLowerCase().trim() || ''; + const filteredProfiles = this.profiles.filter((doc) => + this.matchesSearchText(doc, searchTextValue) && this.matchesSelectedRepo(doc) ); - this.displayProfiles = filteredProfiles?.slice( + + this.totalPages = Math.ceil(filteredProfiles.length / this.profilesPerPage); + this.displayProfiles = filteredProfiles.slice( (this.currentPage - 1) * this.profilesPerPage, this.currentPage * this.profilesPerPage ); } + matchesSearchText(doc: Contributor, searchText: string): boolean { + return !searchText.length || doc.login.toLocaleLowerCase().includes(searchText); + } + + matchesSelectedRepo(doc: Contributor): boolean { + return !this.selectedRepo.length || doc.repos.includes(this.selectedRepo); + } + nextPage() { if (this.currentPage < this.totalPages) { this.currentPage++; From a7df4b58b944a991e1d9fa45d39cab99bacf0691 Mon Sep 17 00:00:00 2001 From: rajutkarsh07 Date: Tue, 12 Nov 2024 13:12:00 +0530 Subject: [PATCH 04/12] css fix --- webiu-ui/src/app/app.component.scss | 339 +++++++++--------- .../components/navbar/navbar.component.scss | 3 + .../profile-card/profile-card.component.scss | 106 +++--- .../contributors/contributors.component.scss | 9 +- webiu-ui/src/styles.scss | 150 +++++--- 5 files changed, 331 insertions(+), 276 deletions(-) diff --git a/webiu-ui/src/app/app.component.scss b/webiu-ui/src/app/app.component.scss index 4998c15d..b460baf1 100644 --- a/webiu-ui/src/app/app.component.scss +++ b/webiu-ui/src/app/app.component.scss @@ -1,284 +1,303 @@ - * { - margin: 0; - padding: 0; - box-sizing: border-box; + margin: 0; + padding: 0; + box-sizing: border-box; } - html { - font-size: 16px; - scroll-behavior: smooth; + font-size: 16px; + scroll-behavior: smooth; } body { - font-family: 'Roboto', sans-serif; - background-color: #f4f7f9; - color: #333; - line-height: 1.6; - margin: 0; - padding: 0; + font-family: "Roboto", sans-serif; + background-color: #f4f7f9; + color: #333; + line-height: 1.6; + margin: 0; + padding: 0; } - .main { - width: 80%; - margin: 0 auto; + width: 80%; + margin: 0 auto; } - -h1, h2, h3, h4, h5, h6 { - font-weight: 700; - color: #222; - margin-bottom: 1rem; +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: 700; + color: #222; } h1 { - font-size: 2.5rem; - line-height: 1.2; + font-size: 2.5rem; + line-height: 1.2; } h2 { - font-size: 2rem; + font-size: 2rem; } h3 { - font-size: 1.75rem; + font-size: 1.75rem; } h4 { - font-size: 1.5rem; + font-size: 1.5rem; } h5 { - font-size: 1.25rem; + font-size: 1.25rem; } h6 { - font-size: 1rem; - font-weight: 600; + font-size: 1rem; + font-weight: 600; } p { - margin-bottom: 1.5rem; - font-size: 1rem; - line-height: 1.8; + font-size: 1rem; + line-height: 1.8; } small { - font-size: 0.85rem; - color: #666; + font-size: 0.85rem; + color: #666; } - a { - color: #3498db; - text-decoration: none; - transition: color 0.3s ease; + color: #3498db; + text-decoration: none; + transition: color 0.3s ease; } a:hover { - color: #2980b9; - text-decoration: underline; + color: #2980b9; + text-decoration: underline; } - -button, .btn { - padding: 0.75rem 1.5rem; - background-color: #3498db; - color: #fff; - border: none; - border-radius: 5px; - cursor: pointer; - font-size: 1rem; - transition: background-color 0.3s ease; +button, +.btn { + padding: 0.75rem 1.5rem; + background-color: #3498db; + color: #fff; + border: none; + border-radius: 5px; + cursor: pointer; + font-size: 1rem; + transition: background-color 0.3s ease; } -button:hover, .btn:hover { - background-color: #2980b9; +button:hover, +.btn:hover { + background-color: #2980b9; } .btn-outline { - background-color: transparent; - border: 2px solid #3498db; - color: #3498db; + background-color: transparent; + border: 2px solid #3498db; + color: #3498db; } .btn-outline:hover { - background-color: #3498db; - color: #fff; + background-color: #3498db; + color: #fff; } - -input, select, textarea { - width: 100%; - padding: 0.75rem; - border: 1px solid #ddd; - border-radius: 5px; - margin-bottom: 1rem; - font-size: 1rem; +input, +select, +textarea { + width: 100%; + padding: 0.75rem; + border: 1px solid #ddd; + border-radius: 5px; + font-size: 1rem; } -input:focus, select:focus, textarea:focus { - outline: none; - border-color: #3498db; - box-shadow: 0 0 5px rgba(52, 152, 219, 0.5); +input:focus, +select:focus, +textarea:focus { + outline: none; + border-color: #3498db; + box-shadow: 0 0 5px rgba(52, 152, 219, 0.5); } - table { - width: 100%; - border-collapse: collapse; - margin-bottom: 2rem; + width: 100%; + border-collapse: collapse; } -table th, table td { - padding: 1rem; - border: 1px solid #ddd; - text-align: left; +table th, +table td { + padding: 1rem; + border: 1px solid #ddd; + text-align: left; } table th { - background-color: #f4f7f9; - font-weight: bold; + background-color: #f4f7f9; + font-weight: bold; } table tr:nth-child(even) { - background-color: #f9f9f9; + background-color: #f9f9f9; } - .container { - max-width: 1200px; - margin: 0 auto; - padding: 0 2rem; + max-width: 1200px; + margin: 0 auto; + padding: 0 2rem; } .row { - display: flex; - flex-wrap: wrap; - margin-left: -1rem; - margin-right: -1rem; + display: flex; + flex-wrap: wrap; + margin-left: -1rem; + margin-right: -1rem; } .col { - flex: 1; - padding: 1rem; + flex: 1; + padding: 1rem; } -.col-2 { flex: 0 0 16.66%; } -.col-3 { flex: 0 0 25%; } -.col-4 { flex: 0 0 33.33%; } -.col-6 { flex: 0 0 50%; } -.col-12 { flex: 0 0 100%; } - +.col-2 { + flex: 0 0 16.66%; +} +.col-3 { + flex: 0 0 25%; +} +.col-4 { + flex: 0 0 33.33%; +} +.col-6 { + flex: 0 0 50%; +} +.col-12 { + flex: 0 0 100%; +} .flex { - display: flex; - justify-content: space-between; - align-items: center; + display: flex; + justify-content: space-between; + align-items: center; } .flex-center { - display: flex; - justify-content: center; - align-items: center; + display: flex; + justify-content: center; + align-items: center; } .flex-column { - display: flex; - flex-direction: column; + display: flex; + flex-direction: column; } - -.mt-1 { margin-top: 1rem; } -.mt-2 { margin-top: 2rem; } -.mb-1 { margin-bottom: 1rem; } -.mb-2 { margin-bottom: 2rem; } -.p-1 { padding: 1rem; } -.p-2 { padding: 2rem; } - +.mt-1 { + margin-top: 1rem; +} +.mt-2 { + margin-top: 2rem; +} +.mb-1 { + margin-bottom: 1rem; +} +.mb-2 { + margin-bottom: 2rem; +} +.p-1 { + padding: 1rem; +} +.p-2 { + padding: 2rem; +} .card { - background-color: #fff; - padding: 1.5rem; - border: 1px solid #ddd; - border-radius: 8px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - transition: box-shadow 0.3s ease; + background-color: #fff; + padding: 1.5rem; + border: 1px solid #ddd; + border-radius: 8px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + transition: box-shadow 0.3s ease; } .card:hover { - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2); } - .fade-in { - animation: fadeIn 1s ease-in forwards; + animation: fadeIn 1s ease-in forwards; } @keyframes fadeIn { - from { - opacity: 0; - } - to { - opacity: 1; - } + from { + opacity: 0; + } + to { + opacity: 1; + } } - @media (max-width: 768px) { - .main { - width: 95%; - } + .main { + width: 95%; + } - h1 { - font-size: 2rem; - } + h1 { + font-size: 2rem; + } - p { - font-size: 0.9rem; - } + p { + font-size: 0.9rem; + } - .row { - flex-direction: column; - } + .row { + flex-direction: column; + } - .col { - flex: 1 0 100%; - } + .col { + flex: 1 0 100%; + } } - body.dark-mode { - background-color: #222; - color: #f4f4f4; + background-color: #222; + color: #f4f4f4; } body.dark-mode a { - color: #3498db; + color: #3498db; } body.dark-mode .card { - background-color: #333; - color: #f4f4f4; + background-color: #333; + color: #f4f4f4; } -body.dark-mode table th, body.dark-mode table td { - border-color: #444; +body.dark-mode table th, +body.dark-mode table td { + border-color: #444; } - .spinner { - border: 4px solid #f3f3f3; - border-radius: 50%; - border-top: 4px solid #3498db; - width: 40px; - height: 40px; - animation: spin 2s linear infinite; + border: 4px solid #f3f3f3; + border-radius: 50%; + border-top: 4px solid #3498db; + width: 40px; + height: 40px; + animation: spin 2s linear infinite; } @keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } } diff --git a/webiu-ui/src/app/components/navbar/navbar.component.scss b/webiu-ui/src/app/components/navbar/navbar.component.scss index fec22532..c8281d41 100644 --- a/webiu-ui/src/app/components/navbar/navbar.component.scss +++ b/webiu-ui/src/app/components/navbar/navbar.component.scss @@ -74,6 +74,9 @@ .navbar__menu__items:hover { background: var(--blue, #2f80ed); color: #fff; + p { + color: #fff; + } } .navbar__menu__items:hover img { diff --git a/webiu-ui/src/app/components/profile-card/profile-card.component.scss b/webiu-ui/src/app/components/profile-card/profile-card.component.scss index 69d3ea72..b9c6a4a9 100644 --- a/webiu-ui/src/app/components/profile-card/profile-card.component.scss +++ b/webiu-ui/src/app/components/profile-card/profile-card.component.scss @@ -1,80 +1,80 @@ .profile-box { - display: flex; - border: solid 1px #e0e0e0; - box-shadow: 10px 10px 30px 10px #0505051a; - border-radius: 10px; - width: 100%; - max-width: 350px; - max-height: 650px; - min-height: 300px; - align-items: center; - justify-content: center; - flex-direction: column; - text-align: center; + display: flex; + border: solid 1px #e0e0e0; + box-shadow: 10px 10px 30px 10px #0505051a; + border-radius: 10px; + width: 100%; + max-width: 350px; + min-height: 300px; + align-items: center; + justify-content: center; + flex-direction: column; + text-align: center; + padding: 20px 0; } .profile-img { - width: 40%; - height: 40%; - border-radius: 50%; - border: solid 0.2px; + width: 40%; + height: 40%; + border-radius: 50%; + border: solid 0.2px; } .profile-info { - display: flex; - width: 100%; - gap: 10%; - justify-content: center; - margin-top: 10px; + display: flex; + width: 100%; + gap: 10%; + justify-content: center; + margin-top: 10px; } .profile-github { - display: flex; - align-items: center; - gap: 10px; - border-radius: 5px; - background: var(--Gray-6, #eeecec); - padding: 8px 12px; - justify-content: center; - margin-top: 5%; + display: flex; + align-items: center; + gap: 10px; + border-radius: 5px; + background: var(--Gray-6, #eeecec); + padding: 8px 12px; + justify-content: center; + margin-top: 5%; } .github-icon { - display: flex; - justify-content: center; - align-items: center; + display: flex; + justify-content: center; + align-items: center; } .github-username { - display: flex; - align-items: center; - color: black; + display: flex; + align-items: center; + color: black; } /* Media Queries */ @media (max-width: 1200px) { - .contributers-context { - grid-template-columns: repeat(3, 1fr); - } - .contributors-main { - margin-left: 15%; - } - .box { - width: 100%; - height: 100%; - } + .contributers-context { + grid-template-columns: repeat(3, 1fr); + } + .contributors-main { + margin-left: 15%; + } + .box { + width: 100%; + height: 100%; + } } @media (max-width: 992px) { - .box { - width: 80%; - height: 80%; - } + .box { + width: 80%; + height: 80%; + } } @media (max-width: 500px) { - .box { - width: 70%; - height: 70%; - } + .box { + width: 70%; + height: 70%; + } } diff --git a/webiu-ui/src/app/page/contributors/contributors.component.scss b/webiu-ui/src/app/page/contributors/contributors.component.scss index d316c03c..15a36230 100644 --- a/webiu-ui/src/app/page/contributors/contributors.component.scss +++ b/webiu-ui/src/app/page/contributors/contributors.component.scss @@ -15,16 +15,18 @@ .search-container { width: 100%; - margin-bottom: 24px; .search-wrapper { display: flex; + align-items: center; + justify-content: center; gap: 12px; width: 100%; + margin-bottom: 2rem; .search-input { flex: 1; - padding: 16px 24px; + padding: 14px 24px; border-radius: 12px; border: 1px solid #e5e5e5; background: #f5f5f5; @@ -81,6 +83,7 @@ .repository-select { background-color: #e9f6ff; + max-width: 300px; } select { @@ -155,7 +158,6 @@ width: 80px; height: 80px; border-radius: 50%; - margin-bottom: 16px; } .profile-info { @@ -168,7 +170,6 @@ .contribution-count { color: var(--gray-900); opacity: 0.8; - margin-bottom: 12px; font-size: 14px; } diff --git a/webiu-ui/src/styles.scss b/webiu-ui/src/styles.scss index 61f9e6be..161bb28e 100644 --- a/webiu-ui/src/styles.scss +++ b/webiu-ui/src/styles.scss @@ -1,22 +1,18 @@ - * { margin: 0; padding: 0; box-sizing: border-box; } - body { font-family: "Poppins", sans-serif; - font-size: 16px; + font-size: 16px; line-height: 1.6; - background-color: #f9f9f9; - color: #333; + color: #333; width: 100%; overflow-x: hidden; } - :root { --primary-color: #3498db; --secondary-color: #2ecc71; @@ -33,8 +29,7 @@ body { --spacing: 16px; } - -[data-theme='dark'] { +[data-theme="dark"] { --primary-color: #2980b9; --secondary-color: #27ae60; --font-color-dark: #f9f9f9; @@ -43,19 +38,20 @@ body { color: var(--font-color-dark); } - -h1, h2, h3, h4, h5, h6 { - margin-bottom: 1.5rem; +h1, +h2, +h3, +h4, +h5, +h6 { font-weight: 700; color: var(--font-color-dark); } p { - margin-bottom: 1rem; color: var(--font-color-dark); } -/* Links */ a { color: var(--primary-color); text-decoration: none; @@ -66,27 +62,61 @@ a:hover { filter: brightness(0.9); } - - -.mt-1 { margin-top: 8px; } -.mt-2 { margin-top: 16px; } -.mt-3 { margin-top: 24px; } -.mb-1 { margin-bottom: 8px; } -.mb-2 { margin-bottom: 16px; } -.mb-3 { margin-bottom: 24px; } -.p-1 { padding: 8px; } -.p-2 { padding: 16px; } -.p-3 { padding: 24px; } -.text-center { text-align: center; } -.text-right { text-align: right; } -.text-left { text-align: left; } -.flex { display: flex; } -.flex-column { display: flex; flex-direction: column; } -.justify-center { justify-content: center; } -.align-center { align-items: center; } -.w-100 { width: 100%; } -.h-100 { height: 100%; } - +.mt-1 { + margin-top: 8px; +} +.mt-2 { + margin-top: 16px; +} +.mt-3 { + margin-top: 24px; +} +.mb-1 { + margin-bottom: 8px; +} +.mb-2 { + margin-bottom: 16px; +} +.mb-3 { + margin-bottom: 24px; +} +.p-1 { + padding: 8px; +} +.p-2 { + padding: 16px; +} +.p-3 { + padding: 24px; +} +.text-center { + text-align: center; +} +.text-right { + text-align: right; +} +.text-left { + text-align: left; +} +.flex { + display: flex; +} +.flex-column { + display: flex; + flex-direction: column; +} +.justify-center { + justify-content: center; +} +.align-center { + align-items: center; +} +.w-100 { + width: 100%; +} +.h-100 { + height: 100%; +} .grid { display: grid; @@ -109,26 +139,28 @@ a:hover { grid-template-columns: auto; } - -input, textarea, select { +input, +textarea, +select { font-family: "Poppins", sans-serif; padding: 0.75rem; border: 1px solid #ddd; border-radius: 5px; width: 100%; - margin-bottom: 1rem; } -input:focus, textarea:focus, select:focus { +input:focus, +textarea:focus, +select:focus { border-color: var(--primary-color); outline: none; } - -button, .btn { +button, +.btn { display: flex; - justify-content: center; - align-items: center; + justify-content: center; + align-items: center; background-color: var(--primary-color); color: var(--font-color-light); padding: 0.75rem 1.5rem; @@ -138,26 +170,27 @@ button, .btn { transition: background-color 0.3s ease; } -button:hover, .btn:hover { +button:hover, +.btn:hover { background-color: var(--hover-color); } -button i, .btn i { +button i, +.btn i { display: inline-block; font-size: 1.25rem; vertical-align: middle; } - -button .icon, .btn .icon { - margin-right: 8px; +button .icon, +.btn .icon { + margin-right: 8px; } - nav { display: flex; - justify-content: center; - align-items: center; + justify-content: center; + align-items: center; background-color: var(--primary-color); padding: 1rem; } @@ -169,7 +202,6 @@ nav ul { margin: 0; } - nav ul li a { color: var(--font-color-light); text-decoration: none; @@ -187,32 +219,32 @@ nav ul li a:hover { color: var(--font-color-light); } - @media (max-width: 768px) { body { font-size: var(--font-size-sm); } - + h1 { font-size: 1.75rem; } - + p { font-size: 0.9rem; } - - button, .btn { + + button, + .btn { font-size: var(--font-size-sm); padding: 0.5rem 1rem; } nav ul { - flex-direction: column; + flex-direction: column; gap: 1rem; } - + nav ul li a { font-size: var(--font-size-sm); padding: 0.5rem 1rem; } -} \ No newline at end of file +} From 9e018081b8268df48fdbd4b214fedf05dca6095f Mon Sep 17 00:00:00 2001 From: rajutkarsh07 Date: Tue, 12 Nov 2024 13:15:21 +0530 Subject: [PATCH 05/12] fixed ci --- .github/workflows/frontend-ci.yml | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/.github/workflows/frontend-ci.yml b/.github/workflows/frontend-ci.yml index 5cf9f243..b282248f 100644 --- a/.github/workflows/frontend-ci.yml +++ b/.github/workflows/frontend-ci.yml @@ -7,8 +7,8 @@ on: branches: [feature/webiu-2024] jobs: - build-and-deploy: - name: Build, Test, and Deploy Angular (webiu-ui) + build-webiu-ui: + name: Build and Test Angular (webiu-ui) runs-on: ubuntu-latest steps: @@ -20,6 +20,16 @@ jobs: with: node-version: '20' + - name: Checkout target branch + uses: actions/checkout@v4 + with: + ref: feature/webiu-2024 + + - name: Fetch pull request changes + run: | + git fetch origin +refs/pull/${{ github.event.pull_request.number }}/merge:pr + git checkout pr + - name: Install Angular CLI run: npm install -g @angular/cli @@ -31,17 +41,9 @@ jobs: - name: Build Angular App run: | cd webiu-ui - ng build --output-path=../docs --base-href="/Webiu/" + npm run build - name: Run Angular Tests - env: - CHROME_BIN: google-chrome - run: | - cd webiu-ui - ng test --watch=false --browsers=ChromeHeadless --no-sandbox - - - name: Deploy to GitHub Pages - if: github.ref == 'refs/heads/feature/webiu-2024' run: | cd webiu-ui - ngh --dir=../docs + npm test From 12e90922389c46f37f9fdf3c3643b7a40e200da8 Mon Sep 17 00:00:00 2001 From: rajutkarsh07 Date: Tue, 12 Nov 2024 13:21:42 +0530 Subject: [PATCH 06/12] refactoring changes --- .github/workflows/frontend-ci.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/frontend-ci.yml b/.github/workflows/frontend-ci.yml index b282248f..7a7b10b7 100644 --- a/.github/workflows/frontend-ci.yml +++ b/.github/workflows/frontend-ci.yml @@ -31,13 +31,20 @@ jobs: git checkout pr - name: Install Angular CLI - run: npm install -g @angular/cli + run: | + cd webiu-ui + npm install -g @angular/cli - name: Install dependencies run: | cd webiu-ui npm install + - name: Install Chrome + run: | + sudo apt-get update + sudo apt-get install -y google-chrome-stable + - name: Build Angular App run: | cd webiu-ui @@ -47,3 +54,4 @@ jobs: run: | cd webiu-ui npm test + npm test -- --browsers=ChromeHeadless --watch=false From f8924659dfa373ce8228e8755a4d72bcea2bb169 Mon Sep 17 00:00:00 2001 From: rajutkarsh07 Date: Tue, 12 Nov 2024 13:25:10 +0530 Subject: [PATCH 07/12] refactor --- .github/workflows/frontend-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/frontend-ci.yml b/.github/workflows/frontend-ci.yml index 7a7b10b7..c50a4d2a 100644 --- a/.github/workflows/frontend-ci.yml +++ b/.github/workflows/frontend-ci.yml @@ -54,4 +54,4 @@ jobs: run: | cd webiu-ui npm test - npm test -- --browsers=ChromeHeadless --watch=false + npm test -- --browsers=ChromeHeadless --watch=false --no-sandbox From f54ddcaf7756d70732c4c0604ec2dfe5e304eddc Mon Sep 17 00:00:00 2001 From: rajutkarsh07 Date: Tue, 12 Nov 2024 13:30:06 +0530 Subject: [PATCH 08/12] fix --- .github/workflows/frontend-ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/frontend-ci.yml b/.github/workflows/frontend-ci.yml index c50a4d2a..aab8893b 100644 --- a/.github/workflows/frontend-ci.yml +++ b/.github/workflows/frontend-ci.yml @@ -53,5 +53,4 @@ jobs: - name: Run Angular Tests run: | cd webiu-ui - npm test - npm test -- --browsers=ChromeHeadless --watch=false --no-sandbox + npm test -- --browsers=ChromeHeadless --watch=false From 2142ee7c0de25bfaf0c04540c70bcab8f0e92ead Mon Sep 17 00:00:00 2001 From: Akshay Waghmare Date: Thu, 14 Nov 2024 20:11:32 +0530 Subject: [PATCH 09/12] Implemented auth system with user model, controller, routes, and tests --- webiu-server/.env.example | 5 + webiu-server/__tests__/authController.test.js | 176 +++ webiu-server/app.js | 13 +- webiu-server/config/db.js | 16 + webiu-server/controllers/authController.js | 103 ++ webiu-server/docs/DOCUMENTATION.md | 131 ++ webiu-server/middlewares/authMiddleware.js | 19 + webiu-server/models/User.js | 22 + webiu-server/package-lock.json | 1399 +++++++++++++++-- webiu-server/package.json | 7 +- webiu-server/routes/authRoutes.js | 9 + webiu-server/server.js | 2 +- webiu-server/utils/jwt.js | 10 + 13 files changed, 1821 insertions(+), 91 deletions(-) create mode 100644 webiu-server/.env.example create mode 100644 webiu-server/__tests__/authController.test.js create mode 100644 webiu-server/config/db.js create mode 100644 webiu-server/controllers/authController.js create mode 100644 webiu-server/docs/DOCUMENTATION.md create mode 100644 webiu-server/middlewares/authMiddleware.js create mode 100644 webiu-server/models/User.js create mode 100644 webiu-server/routes/authRoutes.js create mode 100644 webiu-server/utils/jwt.js diff --git a/webiu-server/.env.example b/webiu-server/.env.example new file mode 100644 index 00000000..2a6beca7 --- /dev/null +++ b/webiu-server/.env.example @@ -0,0 +1,5 @@ +PORT=5100 +MONGODB_URI=mongodb://localhost:27017/webiu +JWT_SECRET=your_jwt_secret +GITHUB_ACCESS_TOKEN=your_github_access_token_add_here + diff --git a/webiu-server/__tests__/authController.test.js b/webiu-server/__tests__/authController.test.js new file mode 100644 index 00000000..1517edfc --- /dev/null +++ b/webiu-server/__tests__/authController.test.js @@ -0,0 +1,176 @@ +const request = require('supertest'); +const express = require('express'); +const User = require('../models/User'); +const { signToken } = require('../utils/jwt'); +const authController = require('../controllers/authController'); + +jest.mock('../utils/jwt', () => ({ + signToken: jest.fn().mockReturnValue('mockedToken'), +})); + +const app = express(); +app.use(express.json()); +app.post('/register', authController.register); +app.post('/login', authController.login); + +describe('Auth Controller Tests', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + // Test successful user registration + it('should register a user successfully', async () => { + const mockUser = { + _id: '60d6f96a9b1f8f001c8f27c5', + name: 'John Doe', + email: 'johndoe@example.com', + password: 'password123', + }; + + User.findOne = jest.fn().mockResolvedValue(null); + User.prototype.save = jest.fn().mockResolvedValue(mockUser); + + const response = await request(app).post('/register').send({ + name: 'John Doe', + email: 'johndoe@example.com', + password: 'password123', + confirmPassword: 'password123', + }); + + response.body.data.user.id = mockUser._id; + + expect(response.status).toBe(201); + expect(response.body.status).toBe('success'); + expect(response.body.data.user).toEqual({ + id: mockUser._id, + name: mockUser.name, + email: mockUser.email, + }); + expect(response.body.data.token).toBe('mockedToken'); + }); + + // Test failed user registration - email already exists + it('should return an error when email already exists during registration', async () => { + const mockUser = { + _id: '60d6f96a9b1f8f001c8f27c5', + name: 'John Doe', + email: 'johndoe@example.com', + password: 'password123', + }; + + User.findOne = jest.fn().mockResolvedValue(mockUser); + + const response = await request(app).post('/register').send({ + name: 'John Doe', + email: 'johndoe@example.com', + password: 'password123', + confirmPassword: 'password123', + }); + + expect(response.status).toBe(400); + expect(response.body.status).toBe('error'); + expect(response.body.message).toBe('User already exists'); + }); + + // Test failed user registration - password mismatch + it('should return an error when passwords do not match', async () => { + const response = await request(app).post('/register').send({ + name: 'John Doe', + email: 'johndoe@example.com', + password: 'password123', + confirmPassword: 'password456', + }); + + expect(response.status).toBe(400); + expect(response.body.status).toBe('error'); + expect(response.body.message).toBe('Passwords do not match'); + }); + + // Test successful user login + it('should login a user successfully', async () => { + const mockUser = { + _id: '60d6f96a9b1f8f001c8f27c5', + email: 'johndoe@example.com', + password: 'password123', + matchPassword: jest.fn().mockResolvedValue(true), + githubId: 'john-github', + }; + + User.findOne = jest.fn().mockResolvedValue(mockUser); + + const response = await request(app).post('/login').send({ + email: 'johndoe@example.com', + password: 'password123', + }); + + expect(response.status).toBe(200); + expect(response.body.status).toBe('success'); + expect(response.body.data.user).toEqual({ + id: mockUser._id, + name: mockUser.name, + email: mockUser.email, + githubId: mockUser.githubId, + }); + expect(response.body.data.token).toBe('mockedToken'); + }); + + // Test failed user login - incorrect password + it('should return an error for incorrect password during login', async () => { + const mockUser = { + _id: '60d6f96a9b1f8f001c8f27c5', + email: 'johndoe@example.com', + password: 'password123', + matchPassword: jest.fn().mockResolvedValue(false), + }; + + User.findOne = jest.fn().mockResolvedValue(mockUser); + + const response = await request(app).post('/login').send({ + email: 'johndoe@example.com', + password: 'wrongPassword', + }); + + expect(response.status).toBe(401); + expect(response.body.status).toBe('error'); + expect(response.body.message).toBe('Invalid email or password'); + }); + + // Test failed user login - user not found + it('should return an error if user is not found during login', async () => { + User.findOne = jest.fn().mockResolvedValue(null); + + const response = await request(app).post('/login').send({ + email: 'nonexistentuser@example.com', + password: 'password123', + }); + + expect(response.status).toBe(401); + expect(response.body.status).toBe('error'); + expect(response.body.message).toBe('User not found'); + }); + + // Test failed user registration - invalid email format + it('should return an error for invalid email format during registration', async () => { + const response = await request(app).post('/register').send({ + name: 'John Doe', + email: 'invalid-email', + password: 'password123', + confirmPassword: 'password123', + }); + + expect(response.status).toBe(400); + expect(response.body.status).toBe('error'); + expect(response.body.message).toBe('Invalid email format'); + }); + + // Test failed user login - missing fields + it('should return an error if required fields are missing during login', async () => { + const response = await request(app).post('/login').send({ + email: 'johndoe@example.com', + }); + + expect(response.status).toBe(401); + expect(response.body.status).toBe('error'); + expect(response.body.message).toBe('User not found'); + }); +}); diff --git a/webiu-server/app.js b/webiu-server/app.js index 9a474bbf..198ed829 100644 --- a/webiu-server/app.js +++ b/webiu-server/app.js @@ -3,15 +3,26 @@ const cookieParser = require('cookie-parser'); const cors = require('cors'); const contributorRoutes = require('./routes/contributorRoutes'); const projectRoutes = require('./routes/projectRoutes'); +const authRoutes = require('./routes/authRoutes') +const connectDB = require('./config/db'); + const app = express(); +connectDB(); app.use(cors()); app.use(express.json()); app.use(cookieParser()); -app.use('/api/v1/project', projectRoutes); +// Route for API-testing +app.get('/api/v1/test', (req, res) => { + res.status(200).json({ message: 'Server is running and working fine!' }); +}); +app.use('/api/v1/project', projectRoutes); app.use('/api/contributor',contributorRoutes); +app.use('/api/v1/auth',authRoutes) + + module.exports = app; diff --git a/webiu-server/config/db.js b/webiu-server/config/db.js new file mode 100644 index 00000000..b86bca94 --- /dev/null +++ b/webiu-server/config/db.js @@ -0,0 +1,16 @@ +const mongoose = require('mongoose'); +require('dotenv').config(); +const colors = require('colors'); + + +const connectDB = async () => { + try { + await mongoose.connect(process.env.MONGODB_URI); + console.log('MongoDB connection established successfully.'.green.bold.underline); + } catch (error) { + console.error('Error: MongoDB connection failed. Please check the database server and configuration.'.red.bold.underline); + process.exit(1); + } +}; + +module.exports = connectDB; diff --git a/webiu-server/controllers/authController.js b/webiu-server/controllers/authController.js new file mode 100644 index 00000000..8e4acfb8 --- /dev/null +++ b/webiu-server/controllers/authController.js @@ -0,0 +1,103 @@ +// controllers/authController.js +const User = require('../models/User'); +const { signToken } = require('../utils/jwt'); + +const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/; + + +const register = async (req, res) => { + const { name, email, password, confirmPassword, githubId } = req.body; + + if (!emailRegex.test(email)) { + return res.status(400).json({ + status: 'error', + message: 'Invalid email format', + }); + } + + if (password !== confirmPassword) { + return res.status(400).json({ + status: 'error', + message: 'Passwords do not match', + }); + } + + try { + const existingUser = await User.findOne({ email }); + if (existingUser) { + return res.status(400).json({ + status: 'error', + message: 'User already exists', + }); + } + + const user = new User({ name, email, password, githubId }); + await user.save(); + + const token = signToken(user); + + res.status(201).json({ + status: 'success', + message: 'User registered successfully', + data: { + user: { + id: user._id, + name: user.name, + email: user.email, + }, + token, + }, + }); + } catch (error) { + res.status(500).json({ + status: 'error', + message: error.message, + }); + } +}; + + +const login = async (req, res) => { + const { email, password } = req.body; + + try { + const user = await User.findOne({ email }); + + if(!user){ + return res.status(401).json({ + status: 'error', + message: 'User not found', + }); + } + if (!user || !(await user.matchPassword(password))) { + return res.status(401).json({ + status: 'error', + message: 'Invalid email or password', + }); + } + + + const token = signToken(user); + + res.status(200).json({ + status: 'success', + message: 'Login successful', + data: { + user: { + id: user._id, + name: user.name, + email: user.email, + githubId:user.githubId + }, + token, + }, + }); + } catch (error) { + res.status(500).json({ + status: 'error', + message: error.message, + }); + } +}; + +module.exports = { register, login }; diff --git a/webiu-server/docs/DOCUMENTATION.md b/webiu-server/docs/DOCUMENTATION.md new file mode 100644 index 00000000..c8a971da --- /dev/null +++ b/webiu-server/docs/DOCUMENTATION.md @@ -0,0 +1,131 @@ + +# API Documentation for Webiu + +## Authentication Endpoints + +### 1. **User Registration** + +- **Endpoint**: `POST /api/v1/auth/register` +- **Description**: Registers a new user with the provided credentials (name, email, password, confirmPassword, githubId). +- **Request Body**: + ```json + { + "name": "John Doe", + "email": "johndoe@example.com", + "password": "password123", + "confirmPassword": "password123", + "githubId": "johndoeGitHub" + } + ``` + +- **Validation**: + - **Email format**: The email must match the valid email pattern (`example@domain.com`). + - **Password match**: The password and confirmPassword must be identical. + +- **Responses**: + - **201 Created**: On successful registration. + ```json + { + "status": "success", + "message": "User registered successfully", + "data": { + "user": { + "id": "userId123", + "name": "John Doe", + "email": "johndoe@example.com" + }, + "token": "JWT_Token_Here" + } + } + ``` + + - **400 Bad Request**: If the email format is invalid or passwords do not match. + ```json + { + "status": "error", + "message": "Invalid email format" + } + ``` + OR + ```json + { + "status": "error", + "message": "Passwords do not match" + } + ``` + + - **400 Bad Request**: If the user already exists with the given email. + ```json + { + "status": "error", + "message": "User already exists" + } + ``` + + - **500 Internal Server Error**: If an unexpected error occurs. + ```json + { + "status": "error", + "message": "Error message here" + } + ``` + +### 2. **User Login** + +- **Endpoint**: `POST /api/v1/auth/login` +- **Description**: Logs in an existing user with the provided email and password. +- **Request Body**: + ```json + { + "email": "johndoe@example.com", + "password": "password123" + } + ``` + +- **Validation**: + - **Email format**: The email must match the valid email pattern (`example@domain.com`). + +- **Responses**: + - **200 OK**: On successful login. + ```json + { + "status": "success", + "message": "Login successful", + "data": { + "user": { + "id": "userId123", + "name": "John Doe", + "email": "johndoe@example.com", + "githubId": "johndoeGitHub" + }, + "token": "JWT_Token_Here" + } + } + ``` + + - **400 Bad Request**: If the email format is invalid. + ```json + { + "status": "error", + "message": "Invalid email format" + } + ``` + + - **401 Unauthorized**: If the user does not exist or if the password is incorrect. + ```json + { + "status": "error", + "message": "Invalid email or password" + } + ``` + + - **500 Internal Server Error**: If an unexpected error occurs. + ```json + { + "status": "error", + "message": "Error message here" + } + ``` + + + diff --git a/webiu-server/middlewares/authMiddleware.js b/webiu-server/middlewares/authMiddleware.js new file mode 100644 index 00000000..cb06476e --- /dev/null +++ b/webiu-server/middlewares/authMiddleware.js @@ -0,0 +1,19 @@ +const jwt = require('jsonwebtoken'); +const User = require('../models/User'); + +const authMiddleware = async (req, res, next) => { + const token = req.header('Authorization').replace('Bearer ', ''); + if (!token) { + return res.status(401).json({ message: 'Not authorized' }); + } + + try { + const decoded = jwt.verify(token, process.env.JWT_SECRET); + req.user = await User.findById(decoded.id); + next(); + } catch (error) { + res.status(401).json({ message: 'Token is not valid' }); + } +}; + +module.exports = authMiddleware; diff --git a/webiu-server/models/User.js b/webiu-server/models/User.js new file mode 100644 index 00000000..c109ce95 --- /dev/null +++ b/webiu-server/models/User.js @@ -0,0 +1,22 @@ +const mongoose = require('mongoose'); +const bcrypt = require('bcryptjs'); + +const userSchema = new mongoose.Schema({ + name: { type: String, required: true }, + email: { type: String, required: true, unique: true }, + password: { type: String, required: true }, + githubId: { type: String }, +}, { timestamps: true }); + +// Hash the password before saving +userSchema.pre('save', async function(next) { + if (!this.isModified('password')) return next(); + this.password = await bcrypt.hash(this.password, 10); + next(); +}); + +userSchema.methods.matchPassword = async function(password) { + return await bcrypt.compare(password, this.password); +}; + +module.exports = mongoose.model('User', userSchema); diff --git a/webiu-server/package-lock.json b/webiu-server/package-lock.json index 9bb2b3fc..3fcaf981 100644 --- a/webiu-server/package-lock.json +++ b/webiu-server/package-lock.json @@ -10,10 +10,15 @@ "license": "ISC", "dependencies": { "axios": "^1.7.2", + "bcryptjs": "^2.4.3", + "chalk": "^5.3.0", + "colors": "^1.4.0", "cookie-parser": "^1.4.6", "cors": "^2.8.5", "dotenv": "^16.4.5", - "express": "^4.19.2", + "express": "^4.21.1", + "jsonwebtoken": "^9.0.2", + "mongoose": "^8.8.1", "nodemon": "^3.1.4", "path": "^0.12.7" }, @@ -671,6 +676,46 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@jest/core": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", @@ -718,6 +763,46 @@ } } }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@jest/environment": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", @@ -833,6 +918,46 @@ } } }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -915,6 +1040,46 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@jest/types": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", @@ -932,6 +1097,46 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -980,6 +1185,15 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz", + "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==", + "license": "MIT", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -1093,6 +1307,21 @@ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "dev": true }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT" + }, + "node_modules/@types/whatwg-url": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", + "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "license": "MIT", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, "node_modules/@types/yargs": { "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", @@ -1227,6 +1456,46 @@ "@babel/core": "^7.8.0" } }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", @@ -1330,6 +1599,12 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==", + "license": "MIT" + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -1342,9 +1617,10 @@ } }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -1354,7 +1630,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -1425,6 +1701,21 @@ "node-int64": "^0.4.0" } }, + "node_modules/bson": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.9.0.tgz", + "integrity": "sha512-X9hJeyeM0//Fus+0pc5dSUMhhrrmWwQUtdavaQeF3Ta6m69matZkGWV/MrBcnwUeLC8W9kwwc2hfkZgUuCX3Ig==", + "license": "Apache-2.0", + "engines": { + "node": ">=16.20.1" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -1435,6 +1726,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1496,42 +1788,17 @@ ] }, "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "license": "MIT", "engines": { - "node": ">=10" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chalk/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", @@ -1633,6 +1900,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1673,6 +1949,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -1747,12 +2024,52 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { + "node_modules/create-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/create-jest/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/create-jest/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" @@ -1765,6 +2082,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -1820,6 +2138,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1828,6 +2147,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -1865,6 +2185,7 @@ "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -1872,10 +2193,20 @@ "url": "https://dotenvx.com" } }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" }, "node_modules/electron-to-chromium": { "version": "1.5.36", @@ -1902,9 +2233,10 @@ "dev": true }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1949,7 +2281,8 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "2.0.0", @@ -1977,6 +2310,7 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2030,36 +2364,37 @@ } }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -2071,9 +2406,10 @@ } }, "node_modules/express/node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2111,12 +2447,13 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -2198,6 +2535,7 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2415,6 +2753,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -2439,6 +2778,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -2779,6 +3119,46 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-cli": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", @@ -2812,6 +3192,46 @@ } } }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-config": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", @@ -2857,6 +3277,46 @@ } } }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-diff": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", @@ -2872,6 +3332,46 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-docblock": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", @@ -2900,6 +3400,46 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-environment-node": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", @@ -2979,6 +3519,46 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-message-util": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", @@ -2999,6 +3579,46 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-mock": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", @@ -3072,6 +3692,46 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-runner": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", @@ -3104,6 +3764,46 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-runtime": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", @@ -3137,6 +3837,46 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-snapshot": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", @@ -3165,7 +3905,47 @@ "semver": "^7.5.3" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/jest-util": { @@ -3185,6 +3965,46 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-validate": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", @@ -3214,6 +4034,46 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-watcher": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", @@ -3233,6 +4093,46 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-worker": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", @@ -3321,6 +4221,64 @@ "node": ">=6" } }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/kareem": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", + "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -3357,6 +4315,48 @@ "node": ">=8" } }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -3394,14 +4394,25 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT" + }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "version": "2.0.0", @@ -3434,6 +4445,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -3480,10 +4492,139 @@ "node": "*" } }, + "node_modules/mongodb": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.10.0.tgz", + "integrity": "sha512-gP9vduuYWb9ZkDM546M+MP2qKVk5ZG2wPF63OvSRuUbqCR+11ZCAE1mOfllhlAG0wcoJY5yDL/rV3OmYEwXIzg==", + "license": "Apache-2.0", + "dependencies": { + "@mongodb-js/saslprep": "^1.1.5", + "bson": "^6.7.0", + "mongodb-connection-string-url": "^3.0.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", + "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", + "license": "Apache-2.0", + "dependencies": { + "@types/whatwg-url": "^11.0.2", + "whatwg-url": "^13.0.0" + } + }, + "node_modules/mongoose": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.8.1.tgz", + "integrity": "sha512-l7DgeY1szT98+EKU8GYnga5WnyatAu+kOQ2VlVX1Mxif6A0Umt0YkSiksCiyGxzx8SPhGe9a53ND1GD4yVDrPA==", + "license": "MIT", + "dependencies": { + "bson": "^6.7.0", + "kareem": "2.6.3", + "mongodb": "~6.10.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "17.1.3" + }, + "engines": { + "node": ">=16.20.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "license": "MIT", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/mquery/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mquery/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/natural-compare": { "version": "1.4.0", @@ -3602,6 +4743,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -3706,6 +4848,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -3753,9 +4896,10 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "license": "MIT" }, "node_modules/picocolors": { "version": "1.1.0", @@ -3864,6 +5008,15 @@ "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/pure-rand": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", @@ -3881,11 +5034,12 @@ ] }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -3898,6 +5052,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -3906,6 +5061,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -4011,7 +5167,8 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/semver": { "version": "7.6.3", @@ -4025,9 +5182,10 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -4047,20 +5205,31 @@ "node": ">= 0.8.0" } }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" @@ -4085,7 +5254,8 @@ "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", @@ -4125,6 +5295,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sift": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==", + "license": "MIT" + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -4176,6 +5352,15 @@ "source-map": "^0.6.0" } }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -4198,6 +5383,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -4406,6 +5592,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "engines": { "node": ">=0.6" } @@ -4418,6 +5605,18 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -4443,6 +5642,7 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -4466,6 +5666,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -4552,6 +5753,28 @@ "makeerror": "1.0.12" } }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "license": "MIT", + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/webiu-server/package.json b/webiu-server/package.json index 4edab96a..27c66c3a 100644 --- a/webiu-server/package.json +++ b/webiu-server/package.json @@ -12,10 +12,15 @@ "license": "ISC", "dependencies": { "axios": "^1.7.2", + "bcryptjs": "^2.4.3", + "chalk": "^5.3.0", + "colors": "^1.4.0", "cookie-parser": "^1.4.6", "cors": "^2.8.5", "dotenv": "^16.4.5", - "express": "^4.19.2", + "express": "^4.21.1", + "jsonwebtoken": "^9.0.2", + "mongoose": "^8.8.1", "nodemon": "^3.1.4", "path": "^0.12.7" }, diff --git a/webiu-server/routes/authRoutes.js b/webiu-server/routes/authRoutes.js new file mode 100644 index 00000000..c85b03f4 --- /dev/null +++ b/webiu-server/routes/authRoutes.js @@ -0,0 +1,9 @@ +// routes/authRoutes.js +const express = require('express'); +const { register, login } = require('../controllers/authController'); +const router = express.Router(); + +router.post('/register', register); +router.post('/login', login); + +module.exports = router; diff --git a/webiu-server/server.js b/webiu-server/server.js index dd7d0c36..ceabda7b 100644 --- a/webiu-server/server.js +++ b/webiu-server/server.js @@ -4,7 +4,7 @@ const path = require('path'); dotenv.config(); const app = require('./app'); -const PORT = process.env.PORT || 5000; +const PORT = process.env.PORT || 5100; const server = app.listen(PORT, () => { console.log(`Server is listening at port ${PORT}`); diff --git a/webiu-server/utils/jwt.js b/webiu-server/utils/jwt.js new file mode 100644 index 00000000..cd30e9c7 --- /dev/null +++ b/webiu-server/utils/jwt.js @@ -0,0 +1,10 @@ +// utils/jwt.js +const jwt = require('jsonwebtoken'); + +const signToken = (user) => { + return jwt.sign({ id: user._id }, process.env.JWT_SECRET, { + expiresIn: '1h', + }); +}; + +module.exports = { signToken }; From 5eb7b16c2725378df92bd3e1e87a0eb679cd5d92 Mon Sep 17 00:00:00 2001 From: utkarsh_raj <49344502+rajutkarsh07@users.noreply.github.com> Date: Thu, 14 Nov 2024 23:18:33 +0530 Subject: [PATCH 10/12] Update server.js --- webiu-server/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webiu-server/server.js b/webiu-server/server.js index ceabda7b..dd7d0c36 100644 --- a/webiu-server/server.js +++ b/webiu-server/server.js @@ -4,7 +4,7 @@ const path = require('path'); dotenv.config(); const app = require('./app'); -const PORT = process.env.PORT || 5100; +const PORT = process.env.PORT || 5000; const server = app.listen(PORT, () => { console.log(`Server is listening at port ${PORT}`); From 5263b31e7b9b1e90873592a42317933da0090ac5 Mon Sep 17 00:00:00 2001 From: Saksham Gupta Date: Mon, 18 Nov 2024 18:33:13 +0530 Subject: [PATCH 11/12] Dark Mode added --- .../components/navbar/navbar.component.html | 12 +- .../components/navbar/navbar.component.scss | 141 +++++++++++++++++- .../app/components/navbar/navbar.component.ts | 13 +- .../profile-card/profile-card.component.scss | 14 +- .../projects-card.component.scss | 21 ++- .../publications-card.component.scss | 6 +- .../page/community/community.component.scss | 4 +- .../contributors/contributors.component.scss | 24 +-- .../src/app/page/gsoc/gsoc.component.html | 2 +- .../src/app/page/gsoc/gsoc.component.scss | 10 +- .../app/page/projects/projects.component.scss | 2 +- .../src/app/services/theme.service.spec.ts | 16 ++ webiu-ui/src/app/services/theme.service.ts | 31 ++++ webiu-ui/src/assets/c2silogo-dark_no_bg.png | Bin 0 -> 50443 bytes webiu-ui/src/assets/gsoc_no_bg.png | Bin 0 -> 33369 bytes webiu-ui/src/styles.scss | 103 +++++++++++-- 16 files changed, 347 insertions(+), 52 deletions(-) create mode 100644 webiu-ui/src/app/services/theme.service.spec.ts create mode 100644 webiu-ui/src/app/services/theme.service.ts create mode 100644 webiu-ui/src/assets/c2silogo-dark_no_bg.png create mode 100644 webiu-ui/src/assets/gsoc_no_bg.png diff --git a/webiu-ui/src/app/components/navbar/navbar.component.html b/webiu-ui/src/app/components/navbar/navbar.component.html index d94e6ab7..5ea18965 100644 --- a/webiu-ui/src/app/components/navbar/navbar.component.html +++ b/webiu-ui/src/app/components/navbar/navbar.component.html @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/webiu-ui/src/app/components/navbar/navbar.component.scss b/webiu-ui/src/app/components/navbar/navbar.component.scss index c8281d41..b9b8e498 100644 --- a/webiu-ui/src/app/components/navbar/navbar.component.scss +++ b/webiu-ui/src/app/components/navbar/navbar.component.scss @@ -4,7 +4,7 @@ padding: 10px 50px; justify-content: space-between; align-items: center; - background: var(--primary-white, #fff); + background: var(--navbar-bg); box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.15); } @@ -28,7 +28,7 @@ right: 20px; align-items: flex-start; width: auto; - background: var(--primary-white, #fff); + background: var(--navbar-bg); box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.15); padding: 10px; border-radius: 8px; @@ -43,7 +43,7 @@ padding: 7px 14px; gap: 8px; border-radius: 7px; - background: var(--primary-white, #fff); + background: var(--primary-white, var(--navbar-bg)); cursor: pointer; transition: all 0.2s; text-align: center; @@ -59,6 +59,7 @@ .navbar__menu__items p { margin: 0; line-height: 1; + color:var(--navbar-p); } /* Active state styling */ @@ -88,6 +89,139 @@ display: none; } +.sun-moon-toggle { + width: 46px; + height: 46px; + box-sizing: border-box; + padding: 12px; + background: none; + border: none; + display: flex; + justify-content: center; + align-items: center; + position: relative; + cursor: pointer; +} + +.sun { + width: 50%; + height: 50%; + position: absolute; + pointer-events: none; + opacity: 0; + transform: scale(0.6) rotate(0deg); + transition: transform 0.3s ease-in, opacity 0.2s ease-in 0.1s; + background: radial-gradient(circle, rgba(0, 0, 0, 0) 50%, #fbbc05 50%); +} + +.sun:before { + content: ""; + position: absolute; + display: block; + width: 100%; + height: 100%; + background: radial-gradient( + circle, + #fbbc05 30%, + rgba(0, 0, 0, 0) 31%, + rgba(0, 0, 0, 0) 50%, + #fbbc05 51% + ); + transform: rotate(45deg); +} + +.sun.visible { + pointer-events: auto; + opacity: 1; + transform: scale(1) rotate(180deg); + transition: transform 0.3s ease-in, opacity 0.2s ease-in 0.1s; +} + + +.moon { + width: 50%; + height: 50%; + pointer-events: none; + position: absolute; + left: 12.5%; + top: 18.75%; + background-color: rgba(0, 0, 0, 0); + border-radius: 50%; + box-shadow: 9px 3px 0px 0px #f0f0f0; + opacity: 0; + transform: scale(0.3) rotate(65deg); + transition: transform 0.3s ease-in, opacity 0.2s ease-in 0.1s; +} + +.moon.visible { + pointer-events: auto; + opacity: 1; + transform: scale(1) rotate(0deg); + transition: transform 0.3s ease-in, opacity 0.2s ease-in 0.1s; +} + +.star { + position: absolute; + top: 25%; + left: 5%; + display: block; + width: 0px; + height: 0px; + border-right: 7px solid rgba(0, 0, 0, 0); + border-bottom: 5px solid #f0f0f0; + border-left: 7px solid rgba(0, 0, 0, 0); + transform: scale(0.55) rotate(35deg); + opacity: 0; + transition: all 0.2s ease-in 0.4s; +} + +.star:before { + border-bottom: 5px solid #f0f0f0; + border-left: 3px solid rgba(0, 0, 0, 0); + border-right: 3px solid rgba(0, 0, 0, 0); + position: absolute; + height: 0; + width: 0; + top: -3px; + left: -5px; + display: block; + content: ""; + transform: rotate(-35deg); +} + +.star:after { + position: absolute; + display: block; + color: red; + top: 0px; + left: -7px; + width: 0px; + height: 0px; + border-right: 7px solid rgba(0, 0, 0, 0); + border-bottom: 5px solid #f0f0f0; + border-left: 7px solid rgba(0, 0, 0, 0); + transform: rotate(-70deg); + content: ""; +} + +.moon.visible .star { + opacity: 0.8; +} + +.star.small { + transform: scale(0.35) rotate(35deg); + position: relative; + top: 50%; + left: 37.5%; + opacity: 0; + transition: all 0.2s ease-in 0.45s; +} + +.moon.visible .star.small { + opacity: 0.7; + transform: scale(0.45) rotate(35deg); +} + @media (max-width: 1100px) { .navbar__menu { display: none !important; @@ -101,3 +235,4 @@ display: block !important; } } + diff --git a/webiu-ui/src/app/components/navbar/navbar.component.ts b/webiu-ui/src/app/components/navbar/navbar.component.ts index 6b61d78a..6b590702 100644 --- a/webiu-ui/src/app/components/navbar/navbar.component.ts +++ b/webiu-ui/src/app/components/navbar/navbar.component.ts @@ -1,6 +1,7 @@ import { Component } from '@angular/core'; import { CommonModule } from '@angular/common'; import { RouterModule } from '@angular/router'; +import { ThemeService } from '../../services/theme.service'; @Component({ selector: 'app-navbar', @@ -11,8 +12,18 @@ import { RouterModule } from '@angular/router'; }) export class NavbarComponent { isMenuOpen = false; - + isSunVisible = true; toggleMenu() { this.isMenuOpen = !this.isMenuOpen; } + constructor(private themeService: ThemeService) { + this.isSunVisible = !this.themeService.isDarkMode(); + } + toggleTheme(): void { + this.themeService.toggleDarkMode(); + } + toggleMode() { + this.isSunVisible = !this.isSunVisible; + this.toggleTheme(); + } } diff --git a/webiu-ui/src/app/components/profile-card/profile-card.component.scss b/webiu-ui/src/app/components/profile-card/profile-card.component.scss index b9c6a4a9..2b011612 100644 --- a/webiu-ui/src/app/components/profile-card/profile-card.component.scss +++ b/webiu-ui/src/app/components/profile-card/profile-card.component.scss @@ -1,7 +1,8 @@ .profile-box { display: flex; - border: solid 1px #e0e0e0; - box-shadow: 10px 10px 30px 10px #0505051a; + border: solid 1px var(--profile-box-border); + background-color: var(--profile-box-bg); + box-shadow: 10px 10px 30px 10px var(--profile-github-box-shadow); border-radius: 10px; width: 100%; max-width: 350px; @@ -33,7 +34,7 @@ align-items: center; gap: 10px; border-radius: 5px; - background: var(--Gray-6, #eeecec); + background: var(--profile-github-bg); padding: 8px 12px; justify-content: center; margin-top: 5%; @@ -43,12 +44,17 @@ display: flex; justify-content: center; align-items: center; + svg { + path { + fill: var(--profile-github-username); + } + } } .github-username { display: flex; align-items: center; - color: black; + color: var(--profile-github-username); } /* Media Queries */ diff --git a/webiu-ui/src/app/components/projects-card/projects-card.component.scss b/webiu-ui/src/app/components/projects-card/projects-card.component.scss index 2c5e6562..5f8b010f 100644 --- a/webiu-ui/src/app/components/projects-card/projects-card.component.scss +++ b/webiu-ui/src/app/components/projects-card/projects-card.component.scss @@ -6,8 +6,8 @@ justify-content: space-between; gap: 20px; border-radius: 8px; - border: 2px solid var(--primary-white, #fff); - background: var(--primary-white, #fff); + border: 2px solid var(--border-color, #fff); + background: var(--card-container-2, #fff); box-shadow: 0px 4px 24px 0px rgba(0, 0, 0, 0.1); .projects__card__main { @@ -72,9 +72,10 @@ color: var(--primary-dark, var(--primary-dark, #0a0a15)); border-radius: 4px; border: 1px solid var(--Gray-5, #e0e0e0); - background: var(--Gray-6, #f2f2f2); + background: var(--card-button-bg); p { + color: var(--card-color-p); width: 100px; font-size: 14px; font-weight: 500; @@ -86,9 +87,12 @@ font-size: 14px; font-weight: 400; border-radius: 20px; - background: var(--primary-white, #fff); + background: var(--card-span, #fff); padding: 6px; } + svg path { + fill: var(--card-color-p); /* Apply dynamic fill color */ + } } .issue-btn { @@ -101,22 +105,27 @@ color: var(--primary-dark, var(--primary-dark, #0a0a15)); border: 1px solid var(--Gray-5, #e0e0e0); - background: var(--Gray-6, #f2f2f2); + background: var(--card-button-bg); span { color: var(--primary-dark, var(--primary-dark, #0a0a15)); font-size: 14px; font-weight: 400; border-radius: 20px; - background: var(--primary-white, #fff); + background: var(--card-span, #fff); padding: 6px; } p { + color: var(--card-color-p); font-size: 14px; font-weight: 500; line-height: 150%; } + svg path { + fill: var(--card-color-p); /* Apply dynamic fill color */ + } + } .git-btn { diff --git a/webiu-ui/src/app/components/publications-card/publications-card.component.scss b/webiu-ui/src/app/components/publications-card/publications-card.component.scss index e24b16db..80b51b1b 100644 --- a/webiu-ui/src/app/components/publications-card/publications-card.component.scss +++ b/webiu-ui/src/app/components/publications-card/publications-card.component.scss @@ -6,9 +6,9 @@ align-items: flex-start; gap: 20px; border-radius: 8px; - border: 2px solid var(--primary-white, #fff); - background: var(--primary-white, #fff); - box-shadow: 0px 4px 24px 0px rgba(0, 0, 0, 0.1); + border: 2px solid var(--publications-card-border); + background: var(--publications-card-bg); + box-shadow: 0px 4px 24px 0px var(--publications-card-box-shadow); width: 500px; a { diff --git a/webiu-ui/src/app/page/community/community.component.scss b/webiu-ui/src/app/page/community/community.component.scss index b51763e2..f91ba937 100644 --- a/webiu-ui/src/app/page/community/community.component.scss +++ b/webiu-ui/src/app/page/community/community.component.scss @@ -74,8 +74,8 @@ align-items: flex-start; gap: 5px; border-radius: 10px; - border: 1px solid var(--Gray-5, #e0e0e0); - background: var(--primary-white, #fff); + border: 1px solid var(--community-card-border); + background: var(--community-card-bg); box-shadow: 0px 4px 15px 0px rgba(0, 0, 0, 0.1); .card-data { diff --git a/webiu-ui/src/app/page/contributors/contributors.component.scss b/webiu-ui/src/app/page/contributors/contributors.component.scss index 15a36230..075afab4 100644 --- a/webiu-ui/src/app/page/contributors/contributors.component.scss +++ b/webiu-ui/src/app/page/contributors/contributors.component.scss @@ -28,21 +28,21 @@ flex: 1; padding: 14px 24px; border-radius: 12px; - border: 1px solid #e5e5e5; - background: #f5f5f5; + border: 1px solid var(--search-border); + background: var(--search-bg); font-size: 16px; - color: #1a1a1a; + color: var(--search-color); outline: none; transition: all 0.2s ease; &::placeholder { - color: #1a1a1a; + color: var(--search-color); opacity: 0.5; } &:focus { border-color: #0066ff; - background: #ffffff; + background: var(--search-bg); } } @@ -77,23 +77,23 @@ gap: 12px; span { - color: var(--gray-900); + color: var(--filter-section-color); font-size: 14px; } .repository-select { - background-color: #e9f6ff; + background-color: var(--select-bg); max-width: 300px; } select { padding: 8px 16px; - border: 1px solid var(--gray-200); + border: 1px solid var(--select-border); border-radius: 6px; font-size: 14px; cursor: pointer; outline: none; - + color: var(--search-color); &:focus { border-color: var(--primary-blue); } @@ -121,9 +121,9 @@ font-size: 16px; cursor: pointer; transition: background-color 0.2s ease; - + &:disabled { - background-color: var(--gray-200); + opacity: 0; // Hide button when disabled cursor: not-allowed; } @@ -134,7 +134,7 @@ span { font-size: 16px; - color: var(--gray-900); + color: var(--pagination-span); } } diff --git a/webiu-ui/src/app/page/gsoc/gsoc.component.html b/webiu-ui/src/app/page/gsoc/gsoc.component.html index 031c0c20..844a31c1 100644 --- a/webiu-ui/src/app/page/gsoc/gsoc.component.html +++ b/webiu-ui/src/app/page/gsoc/gsoc.component.html @@ -9,7 +9,7 @@

C2SI GSOC 2024

page.

- GSOC + GSOC
diff --git a/webiu-ui/src/app/page/gsoc/gsoc.component.scss b/webiu-ui/src/app/page/gsoc/gsoc.component.scss index 1a3630bc..0caf1cae 100644 --- a/webiu-ui/src/app/page/gsoc/gsoc.component.scss +++ b/webiu-ui/src/app/page/gsoc/gsoc.component.scss @@ -62,7 +62,7 @@ font-size: 16px; font-style: italic; font-weight: 400; - line-height: 150%; + line-height: 150%; } } } @@ -73,7 +73,7 @@ flex-direction: column; gap: 20px; border-radius: 10px; - background: var(--Gray-6, #f2f2f2); + background: var(--gsoc-project-list-bg); box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.05) inset; margin: 30px 16px; @@ -82,9 +82,9 @@ padding: 16px; align-items: center; border-radius: 8px; - border: 2px solid var(--primary-white, #fff); - background: var(--primary-white, #fff); - box-shadow: 0px 4px 24px 0px rgba(0, 0, 0, 0.1); + border: 2px solid var(--primary-white, var(--gsoc-project-list-border)); + background: var(--primary-white, var(--gsoc-project-list-bg-2)); + box-shadow: 0px 4px 24px 0px var(--gsoc-project-list-box-shadow); p { font-size: 16px; diff --git a/webiu-ui/src/app/page/projects/projects.component.scss b/webiu-ui/src/app/page/projects/projects.component.scss index 7e558026..75b46a60 100644 --- a/webiu-ui/src/app/page/projects/projects.component.scss +++ b/webiu-ui/src/app/page/projects/projects.component.scss @@ -35,7 +35,7 @@ flex-direction: column; gap: 30px; border-radius: 10px; - background: var(--Gray-6, #f2f2f2); + background: var(--cards-container); box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.05) inset; } } diff --git a/webiu-ui/src/app/services/theme.service.spec.ts b/webiu-ui/src/app/services/theme.service.spec.ts new file mode 100644 index 00000000..1c2957ba --- /dev/null +++ b/webiu-ui/src/app/services/theme.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { ThemeService } from './theme.service'; + +describe('ThemeService', () => { + let service: ThemeService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(ThemeService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/webiu-ui/src/app/services/theme.service.ts b/webiu-ui/src/app/services/theme.service.ts new file mode 100644 index 00000000..5e40a19b --- /dev/null +++ b/webiu-ui/src/app/services/theme.service.ts @@ -0,0 +1,31 @@ +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root', +}) +export class ThemeService { + private readonly DARK_MODE_KEY = 'dark-mode'; + + constructor() { + const isDarkMode = localStorage.getItem(this.DARK_MODE_KEY) === 'true'; + if (isDarkMode) { + document.documentElement.setAttribute('data-theme', 'dark'); + } + } + + toggleDarkMode(): void { + const isDarkMode = document.documentElement.getAttribute('data-theme') === 'dark'; + if (isDarkMode) { + document.documentElement.removeAttribute('data-theme'); + localStorage.setItem(this.DARK_MODE_KEY, 'false'); + } else { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem(this.DARK_MODE_KEY, 'true'); + } + } + + isDarkMode(): boolean { + return document.documentElement.getAttribute('data-theme') === 'dark'; + } + +} \ No newline at end of file diff --git a/webiu-ui/src/assets/c2silogo-dark_no_bg.png b/webiu-ui/src/assets/c2silogo-dark_no_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..94f54ded867f0dcff40a624701e7e1ad9d8b826f GIT binary patch literal 50443 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 z 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 literal 0 HcmV?d00001 diff --git a/webiu-ui/src/assets/gsoc_no_bg.png b/webiu-ui/src/assets/gsoc_no_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..e056e0560851ac93e57873f5ca603c040ed3f1aa GIT binary patch literal 33369 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 Date: Tue, 19 Nov 2024 02:00:41 +0530 Subject: [PATCH 12/12] Dark Mode Requested Changes Done --- .../projects-card.component.scss | 17 ++++-- webiu-ui/src/styles.scss | 60 +++++++++++-------- 2 files changed, 47 insertions(+), 30 deletions(-) diff --git a/webiu-ui/src/app/components/projects-card/projects-card.component.scss b/webiu-ui/src/app/components/projects-card/projects-card.component.scss index 5f8b010f..3a0bc281 100644 --- a/webiu-ui/src/app/components/projects-card/projects-card.component.scss +++ b/webiu-ui/src/app/components/projects-card/projects-card.component.scss @@ -71,7 +71,7 @@ gap: 8px; color: var(--primary-dark, var(--primary-dark, #0a0a15)); border-radius: 4px; - border: 1px solid var(--Gray-5, #e0e0e0); + border: 1px solid var(--card-button-border); background: var(--card-button-bg); p { @@ -104,7 +104,7 @@ border-radius: 4px; color: var(--primary-dark, var(--primary-dark, #0a0a15)); - border: 1px solid var(--Gray-5, #e0e0e0); + border: 1px solid var(--card-button-border); background: var(--card-button-bg); span { @@ -158,10 +158,14 @@ align-items: center; gap: 10px; border-radius: 28px; - border: 1px solid var(--Gray-5, #e0e0e0); - background: var(--primary-white, #fff); + border: 1px solid var(--card-drop-button-border); + background: var(--card-drop-button-bg); box-shadow: 0px 0px 14px 0px rgba(0, 0, 0, 0.1); transition: transform 0.3s ease; + + svg path { + fill: var(--card-drop-button-svg); + } } .projects__card__open__btn.rotate-90 { @@ -190,8 +194,9 @@ .projects__card__tag { font-size: 12px; - border: 2px solid rgba(0, 0, 0, 0.1); - background-color: #f6f6f6; + border: 2px solid var(--card-drop-tag-border); + background-color: var(--card-drop-tag-bg); + color:var(--card-color-p); // box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.2); padding: 4px 6px; border-radius: 20px; diff --git a/webiu-ui/src/styles.scss b/webiu-ui/src/styles.scss index d3cb7266..61b86ebd 100644 --- a/webiu-ui/src/styles.scss +++ b/webiu-ui/src/styles.scss @@ -28,6 +28,12 @@ body { --card-span: #dddddd; --card-button-bg: var(--Gray-6, #f2f2f2); --card-color-p:#0a0a15; + --card-button-border:#e0e0e0; + --card-drop-button-border:#e0e0e0; + --card-drop-button-bg:#fff; + --card-drop-button-svg:black; + --card-drop-tag-border:rgba(0, 0, 0, 0.1); + --card-drop-tag-bg:#f6f6f6; --publications-card-bg: #fff; --publications-card-color: #333; --publications-card-border: #fff; @@ -67,42 +73,48 @@ body { --spacing: 16px; } [data-theme="dark"]{ - background-color: #181a1b; + background-color: #0A0A15; --primary-dark: #fff; --card-dark-2: #dcdcdc; --font-light: #b3b3b3; --font-color-dark: #e0e0e0; - --cards-container:#1f2223; - --card-container-2: var(--native-dark-bg-color); - --card-button-bg: var(--Gray-6, #1f2223); + --cards-container: #1B1B28; + --card-container-2: #11111E; + --card-button-bg: #1B1B28; --native-dark-border-color: #555555; - --border-color: #393d40; - --card-color-p: #cecac3; - --card-span: var(--native-dark-border-color); - --publications-card-bg: #181a1b; - --publications-card-border: #181a1b; + --border-color: #282A3B; + --card-color-p: #ffffff; + --card-span: #11111E; + --card-button-border:#282A3B; + --card-drop-button-border:#FFFFFF33; + --card-drop-button-bg:#1B1B28; + --card-drop-button-svg:#fff; + --card-drop-tag-border:#282A3B; + --card-drop-tag-bg:#1B1B28; + --publications-card-bg: #1B1B28; + --publications-card-border: #282A3B; --publications-card-border-link:#8db2e5; - --search-bg: #1e2021; - --search-border: #373c3e; + --search-bg: #1B1B28; + --search-border: #282A3B; --search-color: #d8d4cf; - --select-border: #3a3e41; - --select-bg:#1e2021; + --select-border: #282A3B; + --select-bg:#1B1B28; --filter-section-color:#e8e6e3; - --profile-box-border:#393d40; - --profile-box-bg:#2e3234; - --profile-github-bg:#222526; + --profile-box-border:#282A3B; + --profile-box-bg:#1B1B28; + --profile-github-bg:#219653; --profile-github-username:white; - --profile-github-box-shadow:#212425; + --profile-github-box-shadow:#292c4949; --pagination-span:#e8e6e3; - --community-card-bg:#1f2223; - --community-card-border:#393d40; + --community-card-bg:#1B1B28; + --community-card-border:#282A3B; --font-color-list: #e8e6e3; --font-color-p:var(--font-color-light); - --gsoc-project-list-bg:#1f2223; - --gsoc-project-list-bg-2:#181a1b; - --gsoc-project-list-border:#303436; - --gsoc-project-list-box-shadow:#2e3234; - --navbar-bg:#1f2223; + --gsoc-project-list-bg:#1B1B28; + --gsoc-project-list-bg-2:#11111E; + --gsoc-project-list-border:#282A3B; + --gsoc-project-list-box-shadow:#292c4949; + --navbar-bg:#11111E; --navbar-p:var(--font-color-light); --publications-card-box-shadow:none; }