+
+
-{% endblock %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/conditional/util/major_project.py b/conditional/util/major_project.py
new file mode 100644
index 00000000..7aa53221
--- /dev/null
+++ b/conditional/util/major_project.py
@@ -0,0 +1,26 @@
+from sqlalchemy import desc, func
+
+from conditional import db, start_of_year
+from conditional.models.models import MajorProject
+from conditional.models.models import MajorProjectSkill
+
+
+def get_project_list():
+ proj_list = db.session.query(
+ MajorProject.id,
+ MajorProject.date,
+ MajorProject.uid,
+ MajorProject.name,
+ MajorProject.tldr,
+ MajorProject.time_spent,
+ MajorProject.description,
+ MajorProject.links,
+ MajorProject.status,
+ func.array_agg(MajorProjectSkill.skill).label("skills")
+ ).outerjoin(MajorProjectSkill,
+ MajorProject.id == MajorProjectSkill.project_id
+ ).group_by(MajorProject.id
+ ).where(MajorProject.date >= start_of_year()
+ ).order_by(desc(MajorProject.date), desc(MajorProject.id))
+
+ return proj_list
diff --git a/conditional/util/s3.py b/conditional/util/s3.py
new file mode 100644
index 00000000..7ce3a999
--- /dev/null
+++ b/conditional/util/s3.py
@@ -0,0 +1,24 @@
+import boto3
+import botocore
+from conditional import app
+
+
+def list_files_in_folder(bucket_name, folder_prefix):
+
+ s3 = boto3.client(
+ service_name="s3",
+ aws_access_key_id=app.config['AWS_ACCESS_KEY_ID'],
+ aws_secret_access_key=app.config['AWS_SECRET_ACCESS_KEY'],
+ endpoint_url=app.config['S3_URI']
+ )
+
+ try:
+ response = s3.list_objects(Bucket=bucket_name, Prefix=folder_prefix)
+ if 'Contents' in response:
+ return [obj['Key'] for obj in response['Contents']]
+
+ return []
+
+ except botocore.exceptions.ClientError as e:
+ print(f"Error listing files in the folder: {e}")
+ return []
diff --git a/config.env.py b/config.env.py
index 554f8e08..d1a39bb5 100644
--- a/config.env.py
+++ b/config.env.py
@@ -26,6 +26,13 @@
LDAP_BIND_DN = env.get("CONDITIONAL_LDAP_BIND_DN", "cn=conditional,ou=Apps,dc=csh,dc=rit,dc=edu")
LDAP_BIND_PW = env.get("CONDITIONAL_LDAP_BIND_PW", "")
+# S3 information
+S3_URI = env.get("S3_URI", "https://s3.csh.rit.edu") # URL for where the s3 bucket is hosted
+S3_BUCKET_ID = env.get("S3_BUCKET_ID", "major-project-media") # name of the bucket
+AWS_ACCESS_KEY_ID = env.get("AWS_ACCESS_KEY_ID", "")
+AWS_SECRET_ACCESS_KEY = env.get("AWS_SECRET_ACCESS_KEY", "")
+
+
# Sentry config
# Not required for local development, but if you set it, make sure the
# SENTRY_ENV is 'local-development'
diff --git a/frontend/images/photo_video.svg b/frontend/images/photo_video.svg
new file mode 100644
index 00000000..2324ec73
--- /dev/null
+++ b/frontend/images/photo_video.svg
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/frontend/javascript/modules/majorProjectForm.js b/frontend/javascript/modules/majorProjectForm.js
index fc9969c1..a19da72d 100644
--- a/frontend/javascript/modules/majorProjectForm.js
+++ b/frontend/javascript/modules/majorProjectForm.js
@@ -1,30 +1,77 @@
import FetchUtil from "../utils/fetchUtil";
export default class MajorProjectForm {
- constructor(form) {
- this.form = form;
- this.endpoint = '/major_project/submit';
- this.render();
- }
-
- render() {
- this.form.querySelector('input[type=submit]')
- .addEventListener('click', e => this._submitForm(e));
- }
-
- _submitForm(e) {
- e.preventDefault();
-
- let payload = {
- projectName: this.form.querySelector('input[name=name]').value,
- projectDescription:
- this.form.querySelector('textarea[name=description]').value
- };
-
- FetchUtil.postWithWarning(this.endpoint, payload, {
- warningText: "You will not be able to edit your " +
- "project once it has been submitted.",
- successText: "Your project has been submitted."
- });
- }
-}
+
+
+ constructor(form) {
+ this.form = form;
+ this.endpoint = '/major_project/submit';
+ this.tags_written = false;
+ this.tag_keys = ["Enter", "Comma", "Tab"];
+ this.render();
+ }
+
+ render() {
+ this.form.querySelector('input[type=submit]')
+ .addEventListener('click', e => this._submitForm(e));
+ this.form.querySelector('input[id=skill-input]')
+ .addEventListener('focusout', e => this.onWriteSkill(e));
+ this.form.querySelector('input[id=skill-input]')
+ .addEventListener('keypress', e => this.onKeyPress(e));
+ }
+
+ onKeyPress(e) {
+ if (this.tag_keys.includes(e.code)) {
+ e.preventDefault();
+ this.onWriteSkill(e);
+ }
+ return false;
+ }
+
+ onWriteSkill(e) {
+ let input = document.getElementById("skill-input")
+ if (!this.tags_written) {
+ this.tags_written = true
+
+ const firstTag = document.getElementsByClassName("skill-tag").item(0);
+ if (firstTag) firstTag.remove();
+ }
+
+ let txt = input.value.replaceAll(/[^a-zA-Z0-9\+\-\.\# ]/g, ''); // allowed characters list
+ if (txt) input.insertAdjacentHTML("beforebegin", '
' + txt + ' ');
+ let skills = this.form.getElementsByClassName("skill-tag")
+ skills.item(skills.length - 1).addEventListener('click', e => this.onRemoveTag(e));
+ input.value = "";
+ }
+
+ onRemoveTag(e) {
+ e.target.remove();
+ }
+
+ _submitForm(e) {
+ e.preventDefault();
+
+ let skills = [];
+
+ for (const tag of this.form.getElementsByClassName('skill-tag')) {
+ skills.push(tag.textContent);
+ }
+
+ let payload = {
+ projectName: this.form.querySelector('input[name=name]').value,
+ projectTldr: this.form.querySelector('input[name=tldr]').value,
+ projectTimeSpent: this.form.querySelector('textarea[name=time-commitment]').value,
+ projectSkills: skills,
+ projectDescription: this.form.querySelector('textarea[name=description]').value,
+ projectLinks: this.form.querySelector('textarea[name=links]').value
+ };
+
+ console.log(payload)
+
+ FetchUtil.postWithWarning(this.endpoint, payload, {
+ warningText: "You will not be able to edit your " +
+ "project once it has been submitted.",
+ successText: "Your project has been submitted."
+ });
+ }
+}
\ No newline at end of file
diff --git a/frontend/javascript/modules/majorProjectStatus.js b/frontend/javascript/modules/majorProjectStatus.js
index 97a68551..7ca87ad3 100644
--- a/frontend/javascript/modules/majorProjectStatus.js
+++ b/frontend/javascript/modules/majorProjectStatus.js
@@ -44,7 +44,7 @@ export default class MajorProjectStatus {
$(dashboardContainer).hide();
} else {
// Major projects page button
- $(this.control.closest(".panel")).fadeOut();
+ $(this.control.closest(".card")).fadeOut();
}
});
} else {
diff --git a/frontend/stylesheets/pages/_dashboard.scss b/frontend/stylesheets/pages/_dashboard.scss
index debdba53..8cc1bc29 100644
--- a/frontend/stylesheets/pages/_dashboard.scss
+++ b/frontend/stylesheets/pages/_dashboard.scss
@@ -41,3 +41,11 @@
margin: 5px 0;
}
}
+
+.section-header {
+ font-size: 1.25em;
+}
+
+div.col {
+ margin-bottom: 1em;
+}
\ No newline at end of file
diff --git a/frontend/stylesheets/pages/_major-project.scss b/frontend/stylesheets/pages/_major-project.scss
index 01438510..d9e70f24 100644
--- a/frontend/stylesheets/pages/_major-project.scss
+++ b/frontend/stylesheets/pages/_major-project.scss
@@ -1,3 +1,135 @@
-.major-project-desc {
- white-space: pre-line;
+.bg-white {
+ background-color: #fff;
}
+
+.px-extra {
+ padding-left: 1em;
+ padding-right: 1em;
+}
+
+.mp-form-intro {
+ background-color: #fff;
+ box-shadow: 1px 1px 2px grey;
+ padding: 1em;
+ padding-bottom: 0.25em;
+ margin-bottom: 2em;
+}
+
+.mp-form {
+ background-color: #fff;
+ box-shadow: 1px 1px 2px grey;
+ margin-bottom: 2em;
+ padding: 1em;
+}
+
+.form-control {
+ margin-bottom: 1em;
+}
+.form-label {
+ margin-top: 1.25rem;
+ font-size: 2rem;
+}
+
+.form-label span {
+ font-size: 1rem;
+}
+
+.form-textarea {
+ resize: vertical;
+}
+
+.form-skilltags {
+ box-shadow: inset 0 -1px 0 #ddd;
+ border: none;
+ border-radius: 0;
+ padding: 0 0 10px;
+ height: fit-content;
+}
+
+.mb-extra {
+ margin-bottom: 2em;
+}
+
+.proj-listing {
+ background-color: #fff;
+ box-shadow: 1px 1px 2px grey;
+}
+
+.rounded-circle {
+ border-radius: 50%;
+}
+
+.placeholder {
+ color: #bbb;
+ font-size: 16px;
+}
+
+.skill-tag {
+ display: block;
+ float: left;
+ background: #b0197e;
+ padding: 4px 30px 4px 8px;
+ margin: 2px 3px;
+ color: #fff;
+ border-radius: 5px;
+ transition: .5s all;
+}
+
+.skill-tag:after {
+ position: absolute;
+ content: "×";
+ border: 1px solid;
+ border-radius: 10px;
+ padding: 0 4px;
+ margin: 3px 0 10px 7px;
+ font-size: 10px;
+}
+
+.skill-display {
+ display: block;
+ float: left;
+ background: #b0197e;
+ padding: 4px 8px 4px 8px;
+ margin: 2px 3px;
+ color: #fff;
+ font-weight: 600;
+ border-radius: 5px;
+ transition: .5s all;
+}
+
+.skill-tag:hover {
+ box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
+}
+
+.skill-group {
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.line-short {
+ line-height: 0.5em;
+}
+
+.line-med {
+ line-height: 1.5em;
+}
+
+.proj-img {
+ max-width: 30%;
+ margin-left: 0.5em;
+ margin-right: 0.5em;
+}
+
+.img-container {
+ display: flex;
+ flex-wrap: wrap;
+ margin-bottom: 1em;
+}
+
+.img-header {
+ margin-left: 1em;
+}
+
+.no-imgs {
+ margin-left: 0.2em;
+}
\ No newline at end of file
diff --git a/migrations/versions/6ae578b76143_.py b/migrations/versions/6ae578b76143_add_date_to_.mp_submission.py
similarity index 100%
rename from migrations/versions/6ae578b76143_.py
rename to migrations/versions/6ae578b76143_add_date_to_.mp_submission.py
diff --git a/migrations/versions/6c4cf35d7c0c_update_mp_table.py b/migrations/versions/6c4cf35d7c0c_update_mp_table.py
new file mode 100644
index 00000000..93a45f86
--- /dev/null
+++ b/migrations/versions/6c4cf35d7c0c_update_mp_table.py
@@ -0,0 +1,43 @@
+"""Add new Major Project data for improved MP form
+
+Revision ID: 6c4cf35d7c0c
+Revises: f1d08673b870
+Create Date: 2026-03-06 15:42:50.323042
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '6c4cf35d7c0c'
+down_revision = 'f1d08673b870'
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.create_table('major_project_skills',
+ sa.Column('project_id', sa.Integer(), nullable=False),
+ sa.Column('skill', sa.Text(), nullable=False),
+ sa.ForeignKeyConstraint(['project_id'], ['major_projects.id'], ondelete='cascade'),
+ sa.PrimaryKeyConstraint('project_id', 'skill')
+ )
+ op.add_column('major_projects', sa.Column('tldr', sa.String(length=128), nullable=True))
+ op.add_column('major_projects', sa.Column('timeSpent', sa.Text(), nullable=True))
+ op.add_column('major_projects', sa.Column('links', sa.Text(), nullable=True))
+ op.alter_column('major_projects', 'description',
+ existing_type=sa.TEXT(),
+ nullable=False)
+ # ### end Alembic commands ###
+
+
+def downgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.alter_column('major_projects', 'description',
+ existing_type=sa.TEXT(),
+ nullable=True)
+ op.drop_column('major_projects', 'links')
+ op.drop_column('major_projects', 'timeSpent')
+ op.drop_column('major_projects', 'tldr')
+ op.drop_table('major_project_skills')
+ # ### end Alembic commands ###
diff --git a/migrations/versions/95538b39976f_mp_time_spent.py b/migrations/versions/95538b39976f_mp_time_spent.py
new file mode 100644
index 00000000..a2dbf0bb
--- /dev/null
+++ b/migrations/versions/95538b39976f_mp_time_spent.py
@@ -0,0 +1,28 @@
+"""Add time spent to mp table
+
+Revision ID: 95538b39976f
+Revises: 6c4cf35d7c0c
+Create Date: 2026-03-09 15:20:23.072283
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '95538b39976f'
+down_revision = '6c4cf35d7c0c'
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.add_column('major_projects', sa.Column('time_spent', sa.Text(), nullable=True))
+ op.drop_column('major_projects', 'timeSpent')
+ # ### end Alembic commands ###
+
+
+def downgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.add_column('major_projects', sa.Column('timeSpent', sa.TEXT(), autoincrement=False, nullable=True))
+ op.drop_column('major_projects', 'time_spent')
+ # ### end Alembic commands ###
diff --git a/package-lock.json b/package-lock.json
index 0f69d912..6084610f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -39,7 +39,7 @@
"sass": "^1.93.3",
"sass-loader": "^16.0.6",
"style-loader": "^4.0.0",
- "webpack": "^5.102.1",
+ "webpack": "^5.105.3",
"webpack-cli": "^6.0.1"
},
"engines": {
@@ -2563,13 +2563,13 @@
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "24.10.0",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz",
- "integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==",
+ "version": "25.3.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.3.tgz",
+ "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "undici-types": "~7.16.0"
+ "undici-types": "~7.18.0"
}
},
"node_modules/@webassemblyjs/ast": {
@@ -2795,9 +2795,9 @@
"license": "Apache-2.0"
},
"node_modules/acorn": {
- "version": "8.15.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
- "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
+ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
"dev": true,
"license": "MIT",
"bin": {
@@ -2981,13 +2981,16 @@
"peer": true
},
"node_modules/baseline-browser-mapping": {
- "version": "2.8.23",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.23.tgz",
- "integrity": "sha512-616V5YX4bepJFzNyOfce5Fa8fDJMfoxzOIzDCZwaGL8MKVpFrXqfNUoIpRn9YMI5pXf/VKgzjB4htFMsFKKdiQ==",
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz",
+ "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==",
"dev": true,
"license": "Apache-2.0",
"bin": {
- "baseline-browser-mapping": "dist/cli.js"
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
}
},
"node_modules/bootstrap": {
@@ -3077,9 +3080,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.27.0",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz",
- "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==",
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
+ "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
"dev": true,
"funding": [
{
@@ -3097,11 +3100,11 @@
],
"license": "MIT",
"dependencies": {
- "baseline-browser-mapping": "^2.8.19",
- "caniuse-lite": "^1.0.30001751",
- "electron-to-chromium": "^1.5.238",
- "node-releases": "^2.0.26",
- "update-browserslist-db": "^1.1.4"
+ "baseline-browser-mapping": "^2.9.0",
+ "caniuse-lite": "^1.0.30001759",
+ "electron-to-chromium": "^1.5.263",
+ "node-releases": "^2.0.27",
+ "update-browserslist-db": "^1.2.0"
},
"bin": {
"browserslist": "cli.js"
@@ -3114,7 +3117,8 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/callsites": {
"version": "3.1.0",
@@ -3128,9 +3132,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001753",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001753.tgz",
- "integrity": "sha512-Bj5H35MD/ebaOV4iDLqPEtiliTN29qkGtEHCwawWn4cYm+bPJM2NsaP30vtZcnERClMzp52J4+aw2UNbK4o+zw==",
+ "version": "1.0.30001775",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001775.tgz",
+ "integrity": "sha512-s3Qv7Lht9zbVKE9XoTyRG6wVDCKdtOFIjBGg3+Yhn6JaytuNKPIjBMTMIY1AnOH3seL5mvF+x33oGAyK3hVt3A==",
"dev": true,
"funding": [
{
@@ -3206,7 +3210,8 @@
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/concat-map": {
"version": "0.0.1",
@@ -3382,21 +3387,21 @@
"license": "MIT"
},
"node_modules/electron-to-chromium": {
- "version": "1.5.244",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.244.tgz",
- "integrity": "sha512-OszpBN7xZX4vWMPJwB9illkN/znA8M36GQqQxi6MNy9axWxhOfJyZZJtSLQCpEFLHP2xK33BiWx9aIuIEXVCcw==",
+ "version": "1.5.302",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz",
+ "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==",
"dev": true,
"license": "ISC"
},
"node_modules/enhanced-resolve": {
- "version": "5.18.3",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
- "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==",
+ "version": "5.20.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz",
+ "integrity": "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.4",
- "tapable": "^2.2.0"
+ "tapable": "^2.3.0"
},
"engines": {
"node": ">=10.13.0"
@@ -3422,9 +3427,9 @@
}
},
"node_modules/es-module-lexer": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
- "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz",
+ "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==",
"dev": true,
"license": "MIT"
},
@@ -3600,7 +3605,6 @@
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=10"
},
@@ -4212,22 +4216,6 @@
"node": ">= 10.13.0"
}
},
- "node_modules/jest-worker/node_modules/supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
- }
- },
"node_modules/jquery": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
@@ -5114,6 +5102,16 @@
"resolved": "https://registry.npmjs.org/simple-masonry/-/simple-masonry-1.0.5.tgz",
"integrity": "sha1-tU6BpzIniokgnbXuPAkYFzIpHmU="
},
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -5124,6 +5122,17 @@
"node": ">=0.10.0"
}
},
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
"node_modules/strip-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz",
@@ -5165,6 +5174,22 @@
"webpack": "^5.27.0"
}
},
+ "node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
@@ -5193,9 +5218,9 @@
}
},
"node_modules/terser": {
- "version": "5.44.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz",
- "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==",
+ "version": "5.46.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz",
+ "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -5245,27 +5270,6 @@
}
}
},
- "node_modules/terser/node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/terser/node_modules/source-map-support": {
- "version": "0.5.21",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
- "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- }
- },
"node_modules/tinyglobby": {
"version": "0.2.15",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
@@ -5329,9 +5333,9 @@
}
},
"node_modules/undici-types": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
- "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
+ "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
"dev": true,
"license": "MIT"
},
@@ -5380,9 +5384,9 @@
}
},
"node_modules/update-browserslist-db": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz",
- "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==",
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
"dev": true,
"funding": [
{
@@ -5429,9 +5433,9 @@
"license": "MIT"
},
"node_modules/watchpack": {
- "version": "2.4.4",
- "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz",
- "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==",
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz",
+ "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5443,9 +5447,9 @@
}
},
"node_modules/webpack": {
- "version": "5.102.1",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.102.1.tgz",
- "integrity": "sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==",
+ "version": "5.105.3",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.3.tgz",
+ "integrity": "sha512-LLBBA4oLmT7sZdHiYE/PeVuifOxYyE2uL/V+9VQP7YSYdJU7bSf7H8bZRRxW8kEPMkmVjnrXmoR3oejIdX0xbg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5455,25 +5459,25 @@
"@webassemblyjs/ast": "^1.14.1",
"@webassemblyjs/wasm-edit": "^1.14.1",
"@webassemblyjs/wasm-parser": "^1.14.1",
- "acorn": "^8.15.0",
+ "acorn": "^8.16.0",
"acorn-import-phases": "^1.0.3",
- "browserslist": "^4.26.3",
+ "browserslist": "^4.28.1",
"chrome-trace-event": "^1.0.2",
- "enhanced-resolve": "^5.17.3",
- "es-module-lexer": "^1.2.1",
+ "enhanced-resolve": "^5.19.0",
+ "es-module-lexer": "^2.0.0",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.2.11",
"json-parse-even-better-errors": "^2.3.1",
- "loader-runner": "^4.2.0",
+ "loader-runner": "^4.3.1",
"mime-types": "^2.1.27",
"neo-async": "^2.6.2",
"schema-utils": "^4.3.3",
"tapable": "^2.3.0",
- "terser-webpack-plugin": "^5.3.11",
- "watchpack": "^2.4.4",
- "webpack-sources": "^3.3.3"
+ "terser-webpack-plugin": "^5.3.16",
+ "watchpack": "^2.5.1",
+ "webpack-sources": "^3.3.4"
},
"bin": {
"webpack": "bin/webpack.js"
@@ -5560,9 +5564,9 @@
}
},
"node_modules/webpack-sources": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz",
- "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==",
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.4.tgz",
+ "integrity": "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==",
"dev": true,
"license": "MIT",
"engines": {
diff --git a/package.json b/package.json
index b39cdc23..7c07ceef 100644
--- a/package.json
+++ b/package.json
@@ -51,7 +51,7 @@
"sass": "^1.93.3",
"sass-loader": "^16.0.6",
"style-loader": "^4.0.0",
- "webpack": "^5.102.1",
+ "webpack": "^5.105.3",
"webpack-cli": "^6.0.1"
}
}
diff --git a/requirements.in b/requirements.in
index c1753f85..0ad7c5f0 100644
--- a/requirements.in
+++ b/requirements.in
@@ -1,6 +1,9 @@
alembic~=1.15.1
astroid~=3.3.9
blinker~=1.4
+boto3==1.35.13
+botocore==1.35.13
+click~=8.1.8
csh_ldap>=2.5.3
ddtrace~=4.4.0
Flask~=3.1.0
diff --git a/requirements.txt b/requirements.txt
index 9a54f1ef..b3e1fe19 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,9 @@
-# This file was autogenerated by uv via the following command:
-# uv pip compile requirements.in
+#
+# This file is autogenerated by pip-compile with Python 3.14
+# by the following command:
+#
+# pip-compile --cert=None --client-cert=None --index-url=None --pip-args=None requirements.in
+#
alembic==1.15.2
# via
# -r requirements.in
@@ -15,6 +19,13 @@ blinker==1.9.0
# -r requirements.in
# flask
# sentry-sdk
+boto3==1.35.13
+ # via -r requirements.in
+botocore==1.35.13
+ # via
+ # -r requirements.in
+ # boto3
+ # s3transfer
build==1.4.0
# via pip-tools
bytecode==0.17.0
@@ -88,7 +99,11 @@ jinja2==3.1.6
# via
# -r requirements.in
# flask
-lazy-object-proxy==1.12.0
+jmespath==1.1.0
+ # via
+ # boto3
+ # botocore
+lazy-object-proxy==1.4.3
# via -r requirements.in
mako==1.3.10
# via
@@ -153,6 +168,13 @@ pyproject-hooks==1.2.0
# build
# pip-tools
python-dotenv==1.2.2
+python-dateutil==2.6.1
+ # via
+ # -r requirements.in
+ # botocore
+ # via
+ # -r requirements.in
+ # botocore
# via pydantic-settings
python-editor==1.0.4
# via -r requirements.in
@@ -163,7 +185,7 @@ requests==2.32.5
# flask-pyoidc
# oic
# pyjwkest
-sentry-sdk==2.24.1
+sentry-sdk[flask]==2.24.1
# via -r requirements.in
setuptools==82.0.0
# via pip-tools
@@ -196,6 +218,7 @@ typing-inspection==0.4.2
# pydantic-settings
urllib3==2.6.3
# via
+ # botocore
# requests
# sentry-sdk
werkzeug==3.1.6
@@ -210,3 +233,7 @@ wrapt==1.17.3
# ddtrace
zipp==3.23.0
# via importlib-metadata
+
+# The following packages are considered to be unsafe in a requirements file:
+# pip
+# setuptools