From ab8e9c27906443f82b19ff4c411e92d820764111 Mon Sep 17 00:00:00 2001
From: kudakwashe siziva <9620622+kaysiz@users.noreply.github.com>
Date: Wed, 16 Apr 2025 16:51:46 +0200
Subject: [PATCH 1/5] ROR API client ID registration (#237)
---
.../api-client-registration-form.hbs | 148 ++++++++++
.../api-client-registration-form.js | 267 +++++++++++++++++
app/router.js | 1 +
app/routes/organizations/api-client-id.js | 4 +
app/services/sanitizer.js | 12 +
app/styles/app.scss | 3 +
.../api-client-registration-form.scss | 98 +++++++
app/templates/organizations/api-client-id.hbs | 25 ++
app/utils/countries.js | 197 +++++++++++++
package.json | 6 +-
yarn.lock | 273 +++++++++++++++++-
11 files changed, 1030 insertions(+), 4 deletions(-)
create mode 100644 app/components/organizations/api-client-registration-form.hbs
create mode 100644 app/components/organizations/api-client-registration-form.js
create mode 100644 app/routes/organizations/api-client-id.js
create mode 100644 app/services/sanitizer.js
create mode 100644 app/styles/components/organizations/api-client-registration-form.scss
create mode 100644 app/templates/organizations/api-client-id.hbs
create mode 100644 app/utils/countries.js
diff --git a/app/components/organizations/api-client-registration-form.hbs b/app/components/organizations/api-client-registration-form.hbs
new file mode 100644
index 00000000..8e90d500
--- /dev/null
+++ b/app/components/organizations/api-client-registration-form.hbs
@@ -0,0 +1,148 @@
+
diff --git a/app/components/organizations/api-client-registration-form.js b/app/components/organizations/api-client-registration-form.js
new file mode 100644
index 00000000..826b87e6
--- /dev/null
+++ b/app/components/organizations/api-client-registration-form.js
@@ -0,0 +1,267 @@
+import Component from '@glimmer/component';
+import { tracked } from '@glimmer/tracking';
+import { action } from '@ember/object';
+import { inject as service } from '@ember/service';
+import countries from 'ror-app/utils/countries';
+
+export default class ApiClientRegistrationFormComponent extends Component {
+ @service sanitizer;
+ @service configService;
+
+ @tracked email = null;
+ @tracked name = null;
+ @tracked institution_name = null;
+ @tracked institution_ror = null;
+ @tracked selectedCountry = null;
+ @tracked country_code = null;
+ @tracked ror_use = null;
+ @tracked isSubmitting = false;
+ @tracked showSuccessMessage = false;
+ @tracked showErrorMessage = false;
+ @tracked emailError = null;
+ @tracked nameError = null;
+ @tracked institutionError = null;
+ @tracked countryError = null;
+ @tracked rorUseError = null;
+ @tracked selectedInstitution = null;
+
+ ROR_API_URL = 'https://api.ror.org/organizations';
+ countries = countries;
+
+ get isFormInvalid() {
+ return this.hasValidationErrors || !this.email || this.isSubmitting;
+ }
+
+ get hasValidationErrors() {
+ return Boolean(
+ this.emailError ||
+ this.nameError ||
+ this.institutionError ||
+ this.countryError ||
+ this.rorUseError
+ );
+ }
+
+ validateEmail(email) {
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+ if (!email) {
+ return 'Email is required';
+ }
+ if (!emailRegex.test(email)) {
+ return 'Please enter a valid email address';
+ }
+ if (email.length > 255) {
+ return 'Email must be less than 255 characters';
+ }
+ return null;
+ }
+
+ validateName(name) {
+ if (name && name.length > 255) {
+ return 'Name must be less than 255 characters';
+ }
+ return null;
+ }
+
+ validateInstitution(name) {
+ if (name && name.length > 255) {
+ return 'Institution name must be less than 255 characters';
+ }
+ return null;
+ }
+
+ validateCountry(country) {
+ if (country && !this.isValidCountryCode(country.code)) {
+ return 'Please select a valid country from the list';
+ }
+ return null;
+ }
+
+ isValidCountryCode(code) {
+ return code && this.countries.some(country => country.code === code);
+ }
+
+ validateRorUse(text) {
+ if (text && text.length > 500) {
+ return 'API usage description must be less than 500 characters';
+ }
+ return null;
+ }
+
+ sanitizeInput(text) {
+ return text ? this.sanitizer.sanitize(text).substring(0, 255) : null;
+ }
+
+ sanitizeRorUse(text) {
+ return text ? this.sanitizer.sanitize(text).substring(0, 500) : null;
+ }
+
+ @action
+ async searchOrganizations(searchTerm) {
+ if (!searchTerm || searchTerm.length < 2) {
+ return [];
+ }
+ try {
+ const response = await fetch(
+ `${this.ROR_API_URL}?query=${encodeURIComponent(searchTerm)}`
+ );
+ const data = await response.json();
+ let results = data.items || [];
+ const exactMatch = results.some(
+ item => item.name.toLowerCase() === searchTerm.toLowerCase()
+ );
+ if (!exactMatch) {
+ const sanitizedInput = this.sanitizeInput(searchTerm);
+ results = [
+ {
+ name: sanitizedInput,
+ id: null,
+ isManualEntry: true
+ },
+ ...results
+ ]
+ }
+ return results;
+ } catch (error) {
+ console.error('Error searching organizations:', error);
+ return [{
+ name: this.sanitizeInput(searchTerm),
+ id: null,
+ isManualEntry: true
+ }];
+ }
+ }
+
+ @action
+ searchCountries(searchTerm) {
+ if (!searchTerm || searchTerm.length < 1) {
+ return this.countries;
+ }
+
+ return this.countries.filter(country =>
+ country.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
+ country.code.toLowerCase().includes(searchTerm.toLowerCase())
+ );
+ }
+
+ @action
+ onInstitutionSelect(selection) {
+ if (selection) {
+ this.selectedInstitution = {
+ name: selection.name,
+ id: selection.id,
+ isManualEntry: selection.isManualEntry || false
+ };
+ if (selection.isManualEntry) {
+ this.institution_name = this.sanitizeInput(selection.name);
+ this.institution_ror = null;
+ } else {
+ this.institution_name = this.sanitizeInput(selection.name);
+ this.institution_ror = selection.id;
+ }
+ this.institutionError = this.validateInstitution(this.institution_name);
+ } else {
+ this.selectedInstitution = null;
+ this.institution_name = null;
+ this.institution_ror = null;
+ this.institutionError = null;
+ }
+ }
+
+ @action
+ onCountrySelect(selection) {
+ this.selectedCountry = selection;
+ this.country_code = selection ? selection.code : null;
+ this.countryError = this.validateCountry(selection);
+ }
+
+ @action
+ validateField(field, value) {
+ switch(field) {
+ case 'email':
+ this.emailError = this.validateEmail(value);
+ break;
+ case 'name':
+ this.nameError = this.validateName(value);
+ break;
+ case 'institution':
+ this.institutionError = this.validateInstitution(value);
+ break;
+ case 'country':
+ this.countryError = this.validateCountry(this.selectedCountry);
+ break;
+ case 'ror_use':
+ this.rorUseError = this.validateRorUse(value);
+ break;
+ }
+ }
+
+ @action
+ onSubmit() {
+
+ this.emailError = this.validateEmail(this.email);
+ this.nameError = this.validateName(this.name);
+ this.institutionError = this.validateInstitution(this.institution_name);
+ this.countryError = this.validateCountry(this.selectedCountry);
+ this.rorUseError = this.validateRorUse(this.ror_use);
+
+ if (this.emailError) {
+ return;
+ }
+
+ this._SubmitForm().catch(error => {
+ console.error('Error submitting form:', error);
+ this.showErrorMessage = true;
+ });
+ }
+
+ async _SubmitForm() {
+ this.isSubmitting = true;
+ this.showErrorMessage = false;
+
+ const formData = {
+ email: this.sanitizeInput(this.email),
+ name: this.sanitizeInput(this.name),
+ institution_name: this.sanitizeInput(this.institution_name),
+ institution_ror: this.institution_ror,
+ country_code: this.country_code,
+ ror_use: this.sanitizeRorUse(this.ror_use)
+ };
+
+ try {
+ const response = await fetch(this.configService.API_URL + '/register', { // TODO: Update this to the correct API endpoint
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(formData)
+ });
+ if (!response.ok) {
+ throw new Error('Registration failed');
+ }
+ this.showSuccessMessage = true;
+ } catch (error) {
+ this.showErrorMessage = true;
+ } finally {
+ this.isSubmitting = false;
+ }
+ }
+
+ @action
+ resetForm() {
+ this.email = null;
+ this.name = null;
+ this.institution_name = null;
+ this.institution_ror = null;
+ this.selectedCountry = null;
+ this.country_code = null;
+ this.ror_use = null;
+ this.showSuccessMessage = false;
+ this.showErrorMessage = false;
+ this.emailError = null;
+ this.nameError = null;
+ this.institutionError = null;
+ this.countryError = null;
+ this.rorUseError = null;
+ }
+}
diff --git a/app/router.js b/app/router.js
index 3c6fe24b..68444240 100644
--- a/app/router.js
+++ b/app/router.js
@@ -11,6 +11,7 @@ Router.map(function() {
this.route('index', { path: '/search' });
this.route('show', { path: '/:organization_id' });
this.route('about', { path: '/' });
+ this.route('api-client-id', { path: '/api-client-id' });
});
});
diff --git a/app/routes/organizations/api-client-id.js b/app/routes/organizations/api-client-id.js
new file mode 100644
index 00000000..58b40ed2
--- /dev/null
+++ b/app/routes/organizations/api-client-id.js
@@ -0,0 +1,4 @@
+import Route from '@ember/routing/route';
+
+export default class OrganizationsRegisterRoute extends Route {
+}
\ No newline at end of file
diff --git a/app/services/sanitizer.js b/app/services/sanitizer.js
new file mode 100644
index 00000000..3f92f867
--- /dev/null
+++ b/app/services/sanitizer.js
@@ -0,0 +1,12 @@
+import Service from '@ember/service';
+import DOMPurify from 'dompurify';
+
+export default class SanitizerService extends Service {
+ sanitize(text) {
+ if (!text) return '';
+ return DOMPurify.sanitize(text, {
+ ALLOWED_TAGS: [], // No HTML tags allowed
+ ALLOWED_ATTR: [] // No HTML attributes allowed
+ });
+ }
+}
diff --git a/app/styles/app.scss b/app/styles/app.scss
index 27b4e957..17d5fb3f 100644
--- a/app/styles/app.scss
+++ b/app/styles/app.scss
@@ -1,3 +1,6 @@
+@import 'ember-power-select';
+@import "components/organizations/api-client-registration-form";
+
$green: #53baa1;
$dark-grey: #505759;
$light-grey: #efefef;
diff --git a/app/styles/components/organizations/api-client-registration-form.scss b/app/styles/components/organizations/api-client-registration-form.scss
new file mode 100644
index 00000000..072da7f8
--- /dev/null
+++ b/app/styles/components/organizations/api-client-registration-form.scss
@@ -0,0 +1,98 @@
+/* app/styles/components/organizations/api-client-registration-form.scss */
+.api-client-registration-form {
+ // Input and Textarea base styles
+ .form-control {
+ border: 1px solid #312d2d;
+ border-radius: 4px;
+ padding: 8px 12px;
+ font-size: 14px;
+ line-height: 1.5;
+ width: 100%;
+ transition: all 0.2s ease-in-out;
+
+ &:focus {
+ border-color: #0000;
+ box-shadow: 0 0 0 2px rgba(255, 109, 133, 0.1);
+ outline: none;
+ }
+ }
+
+ // Textarea specific styles
+ textarea.form-control {
+ min-height: 100px;
+ resize: vertical;
+ }
+
+ // Label styles
+ label.form-label {
+ font-size: 14px;
+ font-weight: 500;
+ color: #333;
+ margin-bottom: 8px;
+ }
+
+ // Form group spacing
+ .form-group {
+ margin-bottom: 1.25rem;
+
+ &:last-of-type {
+ margin-bottom: 1.5rem;
+ }
+ }
+
+ // Optional: Add invalid state styles
+ .is-invalid {
+ border-color: #dc3545;
+
+ &:focus {
+ border-color: #dc3545;
+ box-shadow: 0 0 0 2px rgba(220, 53, 69, 0.25);
+ }
+ }
+
+ // Optional: Add validation message styles
+ .invalid-feedback {
+ display: none;
+ font-size: 12px;
+ color: #dc3545;
+ margin-top: 4px;
+ }
+
+ .form-control.is-invalid + .invalid-feedback {
+ display: block;
+ }
+
+ .ember-power-select-trigger {
+ border: 1px solid #312d2d;
+ border-radius: 4px;
+ padding: 8px 12px;
+ font-size: 14px;
+ line-height: 1.5;
+ min-height: 38px;
+
+ &:focus {
+ border: 1px solid #312d2d;
+ box-shadow: 0 0 0 2px rgba(255, 109, 133, 0.1);
+ outline: none;
+ }
+ }
+
+ .ember-power-select-dropdown {
+ border-color: #E5E5E5;
+ border-radius: 4px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ }
+
+ .ember-power-select-search-input {
+ border: 1px solid #E5E5E5;
+ border-radius: 4px;
+ padding: 8px 12px;
+ font-size: 14px;
+
+ &:focus {
+ border-color: #E5E5E5;
+ outline: none;
+ }
+ }
+
+ }
\ No newline at end of file
diff --git a/app/templates/organizations/api-client-id.hbs b/app/templates/organizations/api-client-id.hbs
new file mode 100644
index 00000000..5c1d17a1
--- /dev/null
+++ b/app/templates/organizations/api-client-id.hbs
@@ -0,0 +1,25 @@
+
+
+
+
Register for a ROR API client ID
+
+
+
ROR API users are encouraged to register for a client ID and to include it in the header of API requests. Requests that include a header named client-id with a valid client ID as its value will receive a rate limit of 2,000 requests/5min. API requests that don't include a client ID will receive a rate limit of 50 requests/5min.
+
+
Please complete the form below to register for a ROR API client ID. Your client ID will be sent to the email address you provide.
+
+
A few notes about ROR API client IDs:
+
+ ROR client IDs are not used for authentication or authorization, and are therefore not secret and can be sent as plain text.
+ We do not provide a way to recover or revoke a lost client ID. If you lose track of your client ID, please register a new client ID.
+ For more information about ROR API client IDs, see https://ror.readme.io/XXXXX
+ For additional help obtaining or using a ROR API client ID contact support@ror.org
+
+
+
+
+
+
+
+
+
diff --git a/app/utils/countries.js b/app/utils/countries.js
new file mode 100644
index 00000000..d22281b6
--- /dev/null
+++ b/app/utils/countries.js
@@ -0,0 +1,197 @@
+export default [
+ { name: "Afghanistan", code: "AF" },
+ { name: "Albania", code: "AL" },
+ { name: "Algeria", code: "DZ" },
+ { name: "Andorra", code: "AD" },
+ { name: "Angola", code: "AO" },
+ { name: "Antigua and Barbuda", code: "AG" },
+ { name: "Argentina", code: "AR" },
+ { name: "Armenia", code: "AM" },
+ { name: "Australia", code: "AU" },
+ { name: "Austria", code: "AT" },
+ { name: "Azerbaijan", code: "AZ" },
+ { name: "Bahamas", code: "BS" },
+ { name: "Bahrain", code: "BH" },
+ { name: "Bangladesh", code: "BD" },
+ { name: "Barbados", code: "BB" },
+ { name: "Belarus", code: "BY" },
+ { name: "Belgium", code: "BE" },
+ { name: "Belize", code: "BZ" },
+ { name: "Benin", code: "BJ" },
+ { name: "Bhutan", code: "BT" },
+ { name: "Bolivia", code: "BO" },
+ { name: "Bosnia and Herzegovina", code: "BA" },
+ { name: "Botswana", code: "BW" },
+ { name: "Brazil", code: "BR" },
+ { name: "Brunei", code: "BN" },
+ { name: "Bulgaria", code: "BG" },
+ { name: "Burkina Faso", code: "BF" },
+ { name: "Burundi", code: "BI" },
+ { name: "Cabo Verde", code: "CV" },
+ { name: "Cambodia", code: "KH" },
+ { name: "Cameroon", code: "CM" },
+ { name: "Canada", code: "CA" },
+ { name: "Central African Republic", code: "CF" },
+ { name: "Chad", code: "TD" },
+ { name: "Chile", code: "CL" },
+ { name: "China", code: "CN" },
+ { name: "Colombia", code: "CO" },
+ { name: "Comoros", code: "KM" },
+ { name: "Congo (Congo-Brazzaville)", code: "CG" },
+ { name: "Costa Rica", code: "CR" },
+ { name: "Croatia", code: "HR" },
+ { name: "Cuba", code: "CU" },
+ { name: "Cyprus", code: "CY" },
+ { name: "Czech Republic", code: "CZ" },
+ { name: "Denmark", code: "DK" },
+ { name: "Djibouti", code: "DJ" },
+ { name: "Dominica", code: "DM" },
+ { name: "Dominican Republic", code: "DO" },
+ { name: "DR Congo (Congo-Kinshasa)", code: "CD" },
+ { name: "Ecuador", code: "EC" },
+ { name: "Egypt", code: "EG" },
+ { name: "El Salvador", code: "SV" },
+ { name: "Equatorial Guinea", code: "GQ" },
+ { name: "Eritrea", code: "ER" },
+ { name: "Estonia", code: "EE" },
+ { name: "Eswatini", code: "SZ" },
+ { name: "Ethiopia", code: "ET" },
+ { name: "Fiji", code: "FJ" },
+ { name: "Finland", code: "FI" },
+ { name: "France", code: "FR" },
+ { name: "Gabon", code: "GA" },
+ { name: "Gambia", code: "GM" },
+ { name: "Georgia", code: "GE" },
+ { name: "Germany", code: "DE" },
+ { name: "Ghana", code: "GH" },
+ { name: "Greece", code: "GR" },
+ { name: "Grenada", code: "GD" },
+ { name: "Guatemala", code: "GT" },
+ { name: "Guinea", code: "GN" },
+ { name: "Guinea-Bissau", code: "GW" },
+ { name: "Guyana", code: "GY" },
+ { name: "Haiti", code: "HT" },
+ { name: "Honduras", code: "HN" },
+ { name: "Hungary", code: "HU" },
+ { name: "Iceland", code: "IS" },
+ { name: "India", code: "IN" },
+ { name: "Indonesia", code: "ID" },
+ { name: "Iran", code: "IR" },
+ { name: "Iraq", code: "IQ" },
+ { name: "Ireland", code: "IE" },
+ { name: "Israel", code: "IL" },
+ { name: "Italy", code: "IT" },
+ { name: "Jamaica", code: "JM" },
+ { name: "Japan", code: "JP" },
+ { name: "Jordan", code: "JO" },
+ { name: "Kazakhstan", code: "KZ" },
+ { name: "Kenya", code: "KE" },
+ { name: "Kiribati", code: "KI" },
+ { name: "Korea, North", code: "KP" },
+ { name: "Korea, South", code: "KR" },
+ { name: "Kuwait", code: "KW" },
+ { name: "Kyrgyzstan", code: "KG" },
+ { name: "Laos", code: "LA" },
+ { name: "Latvia", code: "LV" },
+ { name: "Lebanon", code: "LB" },
+ { name: "Lesotho", code: "LS" },
+ { name: "Liberia", code: "LR" },
+ { name: "Libya", code: "LY" },
+ { name: "Liechtenstein", code: "LI" },
+ { name: "Lithuania", code: "LT" },
+ { name: "Luxembourg", code: "LU" },
+ { name: "Madagascar", code: "MG" },
+ { name: "Malawi", code: "MW" },
+ { name: "Malaysia", code: "MY" },
+ { name: "Maldives", code: "MV" },
+ { name: "Mali", code: "ML" },
+ { name: "Malta", code: "MT" },
+ { name: "Marshall Islands", code: "MH" },
+ { name: "Mauritania", code: "MR" },
+ { name: "Mauritius", code: "MU" },
+ { name: "Mexico", code: "MX" },
+ { name: "Micronesia", code: "FM" },
+ { name: "Moldova", code: "MD" },
+ { name: "Monaco", code: "MC" },
+ { name: "Mongolia", code: "MN" },
+ { name: "Montenegro", code: "ME" },
+ { name: "Morocco", code: "MA" },
+ { name: "Mozambique", code: "MZ" },
+ { name: "Myanmar", code: "MM" },
+ { name: "Namibia", code: "NA" },
+ { name: "Nauru", code: "NR" },
+ { name: "Nepal", code: "NP" },
+ { name: "Netherlands", code: "NL" },
+ { name: "New Zealand", code: "NZ" },
+ { name: "Nicaragua", code: "NI" },
+ { name: "Niger", code: "NE" },
+ { name: "Nigeria", code: "NG" },
+ { name: "North Macedonia", code: "MK" },
+ { name: "Norway", code: "NO" },
+ { name: "Oman", code: "OM" },
+ { name: "Pakistan", code: "PK" },
+ { name: "Palau", code: "PW" },
+ { name: "Palestine", code: "PS" },
+ { name: "Panama", code: "PA" },
+ { name: "Papua New Guinea", code: "PG" },
+ { name: "Paraguay", code: "PY" },
+ { name: "Peru", code: "PE" },
+ { name: "Philippines", code: "PH" },
+ { name: "Poland", code: "PL" },
+ { name: "Portugal", code: "PT" },
+ { name: "Qatar", code: "QA" },
+ { name: "Romania", code: "RO" },
+ { name: "Russia", code: "RU" },
+ { name: "Rwanda", code: "RW" },
+ { name: "Saint Kitts and Nevis", code: "KN" },
+ { name: "Saint Lucia", code: "LC" },
+ { name: "Saint Vincent and the Grenadines", code: "VC" },
+ { name: "Samoa", code: "WS" },
+ { name: "San Marino", code: "SM" },
+ { name: "Sao Tome and Principe", code: "ST" },
+ { name: "Saudi Arabia", code: "SA" },
+ { name: "Senegal", code: "SN" },
+ { name: "Serbia", code: "RS" },
+ { name: "Seychelles", code: "SC" },
+ { name: "Sierra Leone", code: "SL" },
+ { name: "Singapore", code: "SG" },
+ { name: "Slovakia", code: "SK" },
+ { name: "Slovenia", code: "SI" },
+ { name: "Solomon Islands", code: "SB" },
+ { name: "Somalia", code: "SO" },
+ { name: "South Africa", code: "ZA" },
+ { name: "South Sudan", code: "SS" },
+ { name: "Spain", code: "ES" },
+ { name: "Sri Lanka", code: "LK" },
+ { name: "Sudan", code: "SD" },
+ { name: "Suriname", code: "SR" },
+ { name: "Sweden", code: "SE" },
+ { name: "Switzerland", code: "CH" },
+ { name: "Syria", code: "SY" },
+ { name: "Taiwan", code: "TW" },
+ { name: "Tajikistan", code: "TJ" },
+ { name: "Tanzania", code: "TZ" },
+ { name: "Thailand", code: "TH" },
+ { name: "Timor-Leste", code: "TL" },
+ { name: "Togo", code: "TG" },
+ { name: "Tonga", code: "TO" },
+ { name: "Trinidad and Tobago", code: "TT" },
+ { name: "Tunisia", code: "TN" },
+ { name: "Turkey", code: "TR" },
+ { name: "Turkmenistan", code: "TM" },
+ { name: "Tuvalu", code: "TV" },
+ { name: "Uganda", code: "UG" },
+ { name: "Ukraine", code: "UA" },
+ { name: "United Arab Emirates", code: "AE" },
+ { name: "United Kingdom", code: "GB" },
+ { name: "United States", code: "US" },
+ { name: "Uruguay", code: "UY" },
+ { name: "Uzbekistan", code: "UZ" },
+ { name: "Vanuatu", code: "VU" },
+ { name: "Vatican City", code: "VA" },
+ { name: "Venezuela", code: "VE" },
+ { name: "Vietnam", code: "VN" },
+ { name: "Yemen", code: "YE" },
+ { name: "Zambia", code: "ZM" },
+ { name: "Zimbabwe", code: "ZW" }
+];
\ No newline at end of file
diff --git a/package.json b/package.json
index faaf593a..a8eddd89 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,8 @@
"dependencies": {
"@babel/helper-explode-assignable-expression": "^7.18.6",
"@sentry/browser": "^7.110.1",
- "@sentry/integrations": "^5.10.2"
+ "@sentry/integrations": "^5.10.2",
+ "dompurify": "^3.2.4"
},
"devDependencies": {
"@ember/optional-features": "^2.1.0",
@@ -35,6 +36,7 @@
"broccoli-asset-rev": "^3.0.0",
"ember-ajax": "^5.1.2",
"ember-auto-import": "^2.7.2",
+ "ember-basic-dropdown": "^8.6.0",
"ember-bootstrap": "^5.0.0",
"ember-cli": "^4.9.2",
"ember-cli-app-version": "^6.0.0",
@@ -48,11 +50,13 @@
"ember-cli-sri": "^2.1.1",
"ember-cli-string-helpers": "^6.1.0",
"ember-cli-terser": "^4.0.2",
+ "ember-concurrency": "^4.0.3",
"ember-data": "~3.28.6",
"ember-export-application-global": "^2.0.1",
"ember-load-initializers": "^2.1.2",
"ember-maybe-import-regenerator": "^1.0.0",
"ember-moment": "^10.0.0",
+ "ember-power-select": "^8.7.0",
"ember-qunit": "^5.1.5",
"ember-resolver": "^9.0.1",
"ember-source": "~3.28.8",
diff --git a/yarn.lock b/yarn.lock
index a05944d4..4ab3b7fe 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -18,6 +18,15 @@
"@babel/highlight" "^7.24.7"
picocolors "^1.0.0"
+"@babel/code-frame@^7.26.2":
+ version "7.26.2"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85"
+ integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.25.9"
+ js-tokens "^4.0.0"
+ picocolors "^1.0.0"
+
"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.2":
version "7.25.2"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.2.tgz#e41928bd33475305c586f6acbbb7e3ade7a6f7f5"
@@ -64,6 +73,17 @@
"@jridgewell/trace-mapping" "^0.3.25"
jsesc "^2.5.1"
+"@babel/generator@^7.26.9":
+ version "7.26.9"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.9.tgz#75a9482ad3d0cc7188a537aa4910bc59db67cbca"
+ integrity sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==
+ dependencies:
+ "@babel/parser" "^7.26.9"
+ "@babel/types" "^7.26.9"
+ "@jridgewell/gen-mapping" "^0.3.5"
+ "@jridgewell/trace-mapping" "^0.3.25"
+ jsesc "^3.0.2"
+
"@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@^7.24.7":
version "7.24.7"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz#5373c7bc8366b12a033b4be1ac13a206c6656aab"
@@ -138,6 +158,14 @@
"@babel/traverse" "^7.24.8"
"@babel/types" "^7.24.8"
+"@babel/helper-module-imports@^7.22.15":
+ version "7.25.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz#e7f8d20602ebdbf9ebbea0a0751fb0f2a4141715"
+ integrity sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==
+ dependencies:
+ "@babel/traverse" "^7.25.9"
+ "@babel/types" "^7.25.9"
+
"@babel/helper-module-imports@^7.24.7", "@babel/helper-module-imports@^7.8.3":
version "7.24.7"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b"
@@ -168,6 +196,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz#94ee67e8ec0e5d44ea7baeb51e571bd26af07878"
integrity sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==
+"@babel/helper-plugin-utils@^7.25.9":
+ version "7.26.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz#18580d00c9934117ad719392c4f6585c9333cc35"
+ integrity sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==
+
"@babel/helper-remap-async-to-generator@^7.24.7", "@babel/helper-remap-async-to-generator@^7.25.0":
version "7.25.0"
resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz#d2f0fbba059a42d68e5e378feaf181ef6055365e"
@@ -207,11 +240,21 @@
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d"
integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==
+"@babel/helper-string-parser@^7.25.9":
+ version "7.25.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c"
+ integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==
+
"@babel/helper-validator-identifier@^7.24.7":
version "7.24.7"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db"
integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==
+"@babel/helper-validator-identifier@^7.25.9":
+ version "7.25.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7"
+ integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==
+
"@babel/helper-validator-option@^7.24.8":
version "7.24.8"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d"
@@ -258,6 +301,13 @@
dependencies:
"@babel/types" "^7.25.6"
+"@babel/parser@^7.26.9":
+ version "7.26.9"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.9.tgz#d9e78bee6dc80f9efd8f2349dcfbbcdace280fd5"
+ integrity sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==
+ dependencies:
+ "@babel/types" "^7.26.9"
+
"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.3":
version "7.25.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz#dca427b45a6c0f5c095a1c639dfe2476a3daba7f"
@@ -365,6 +415,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.24.7"
+"@babel/plugin-syntax-decorators@^7.23.3":
+ version "7.25.9"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.25.9.tgz#986b4ca8b7b5df3f67cee889cedeffc2e2bf14b3"
+ integrity sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.25.9"
+
"@babel/plugin-syntax-dynamic-import@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3"
@@ -1052,6 +1109,15 @@
"@babel/parser" "^7.25.0"
"@babel/types" "^7.25.0"
+"@babel/template@^7.26.9":
+ version "7.26.9"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.26.9.tgz#4577ad3ddf43d194528cff4e1fa6b232fa609bb2"
+ integrity sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==
+ dependencies:
+ "@babel/code-frame" "^7.26.2"
+ "@babel/parser" "^7.26.9"
+ "@babel/types" "^7.26.9"
+
"@babel/traverse@^7.1.6", "@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.1", "@babel/traverse@^7.25.2", "@babel/traverse@^7.25.3", "@babel/traverse@^7.4.5":
version "7.25.3"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.3.tgz#f1b901951c83eda2f3e29450ce92743783373490"
@@ -1065,6 +1131,19 @@
debug "^4.3.1"
globals "^11.1.0"
+"@babel/traverse@^7.25.9":
+ version "7.26.9"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.26.9.tgz#4398f2394ba66d05d988b2ad13c219a2c857461a"
+ integrity sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==
+ dependencies:
+ "@babel/code-frame" "^7.26.2"
+ "@babel/generator" "^7.26.9"
+ "@babel/parser" "^7.26.9"
+ "@babel/template" "^7.26.9"
+ "@babel/types" "^7.26.9"
+ debug "^4.3.1"
+ globals "^11.1.0"
+
"@babel/traverse@^7.7.0":
version "7.25.6"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.6.tgz#04fad980e444f182ecf1520504941940a90fea41"
@@ -1105,6 +1184,14 @@
"@babel/helper-validator-identifier" "^7.24.7"
to-fast-properties "^2.0.0"
+"@babel/types@^7.25.9", "@babel/types@^7.26.9":
+ version "7.26.9"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.9.tgz#08b43dec79ee8e682c2ac631c010bdcac54a21ce"
+ integrity sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==
+ dependencies:
+ "@babel/helper-string-parser" "^7.25.9"
+ "@babel/helper-validator-identifier" "^7.25.9"
+
"@cnakazawa/watch@^1.0.3":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a"
@@ -1329,6 +1416,16 @@
common-ancestor-path "^1.0.1"
semver "^7.3.8"
+"@embroider/addon-shim@^1.6.0", "@embroider/addon-shim@^1.8.3", "@embroider/addon-shim@^1.8.7", "@embroider/addon-shim@^1.9.0":
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/@embroider/addon-shim/-/addon-shim-1.9.0.tgz#f729cfaf0f2d5f3c178808a546251743335c62f4"
+ integrity sha512-fMzayl/licUL8VRAy4qXROKcYvHwUbV8aTh4m97L5/MRuVpxbcAy92DGGTqx5OBKCSQN3gMg+sUKeE6AviefpQ==
+ dependencies:
+ "@embroider/shared-internals" "^2.8.1"
+ broccoli-funnel "^3.0.8"
+ common-ancestor-path "^1.0.1"
+ semver "^7.3.8"
+
"@embroider/macros@^1.0.0", "@embroider/macros@^1.10.0", "@embroider/macros@^1.16.5":
version "1.16.5"
resolved "https://registry.yarnpkg.com/@embroider/macros/-/macros-1.16.5.tgz#871addab2103b554c6b6a3a337c00e3f0a0462ac"
@@ -1343,6 +1440,20 @@
resolve "^1.20.0"
semver "^7.3.2"
+"@embroider/macros@^1.16.10":
+ version "1.16.11"
+ resolved "https://registry.yarnpkg.com/@embroider/macros/-/macros-1.16.11.tgz#c8c8c58dac21dd911379ae31fe4f5a53a5cc5a69"
+ integrity sha512-TUm/74oBr+tWto0IPAht1g6zjpP7UK0aQdnFHHqGvDPc+tAROQb9jKI/ePEuKAdBCV3L7XvvC4Rlf0DNvT4qmw==
+ dependencies:
+ "@embroider/shared-internals" "2.9.0"
+ assert-never "^1.2.1"
+ babel-import-util "^2.0.0"
+ ember-cli-babel "^7.26.6"
+ find-up "^5.0.0"
+ lodash "^4.17.21"
+ resolve "^1.20.0"
+ semver "^7.3.2"
+
"@embroider/shared-internals@2.6.2", "@embroider/shared-internals@^2.0.0", "@embroider/shared-internals@^2.6.0":
version "2.6.2"
resolved "https://registry.yarnpkg.com/@embroider/shared-internals/-/shared-internals-2.6.2.tgz#66297a8606587108f9dbcbaa1a9dcc6b4a4ca605"
@@ -1359,6 +1470,24 @@
semver "^7.3.5"
typescript-memoize "^1.0.1"
+"@embroider/shared-internals@2.9.0", "@embroider/shared-internals@^2.8.1":
+ version "2.9.0"
+ resolved "https://registry.yarnpkg.com/@embroider/shared-internals/-/shared-internals-2.9.0.tgz#5d945b92e08db163de60d82f7c388e2b7260f0cc"
+ integrity sha512-8untWEvGy6av/oYibqZWMz/yB+LHsKxEOoUZiLvcpFwWj2Sipc0DcXeTJQZQZ++otNkLCWyDrDhOLrOkgjOPSg==
+ dependencies:
+ babel-import-util "^2.0.0"
+ debug "^4.3.2"
+ ember-rfc176-data "^0.3.17"
+ fs-extra "^9.1.0"
+ is-subdir "^1.2.0"
+ js-string-escape "^1.0.1"
+ lodash "^4.17.21"
+ minimatch "^3.0.4"
+ pkg-entry-points "^1.1.0"
+ resolve-package-path "^4.0.1"
+ semver "^7.3.5"
+ typescript-memoize "^1.0.1"
+
"@embroider/shared-internals@^1.0.0":
version "1.8.3"
resolved "https://registry.yarnpkg.com/@embroider/shared-internals/-/shared-internals-1.8.3.tgz#52d868dc80016e9fe983552c0e516f437bf9b9f9"
@@ -1373,7 +1502,7 @@
semver "^7.3.5"
typescript-memoize "^1.0.1"
-"@embroider/util@^0.39.1 || ^0.40.0 || ^0.41.0 || ^1.0.0", "@embroider/util@^1.0.0", "@embroider/util@^1.9.0":
+"@embroider/util@^0.39.1 || ^0.40.0 || ^0.41.0 || ^1.0.0", "@embroider/util@^1.0.0", "@embroider/util@^1.13.2", "@embroider/util@^1.9.0":
version "1.13.2"
resolved "https://registry.yarnpkg.com/@embroider/util/-/util-1.13.2.tgz#446f5861ca387b523cf033640265ae820cc1d7aa"
integrity sha512-6/0sK4dtFK7Ld+t5Ovn9EilBVySoysMRdDAf/jGteOO7jdLKNgHnONg0w1T7ZZaMFUQfwJdRrk3u0dM+Idhiew==
@@ -1890,6 +2019,11 @@
resolved "https://registry.yarnpkg.com/@types/symlink-or-copy/-/symlink-or-copy-1.2.2.tgz#51b1c00b516a5774ada5d611e65eb123f988ef8d"
integrity sha512-MQ1AnmTLOncwEf9IVU+B2e4Hchrku5N67NkgcAHW0p3sdzPe0FNMANxEm6OJUzPniEQGkeT3OROLlCwZJLWFZA==
+"@types/trusted-types@^2.0.7":
+ version "2.0.7"
+ resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11"
+ integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==
+
"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1":
version "1.12.1"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb"
@@ -2668,7 +2802,7 @@ babel-import-util@^1.1.0:
resolved "https://registry.yarnpkg.com/babel-import-util/-/babel-import-util-1.4.1.tgz#1df6fd679845df45494bac9ca12461d49497fdd4"
integrity sha512-TNdiTQdPhXlx02pzG//UyVPSKE7SNWjY0n4So/ZnjQpWwaM5LvWBLkWa1JKll5u06HNscHD91XZPuwrMg1kadQ==
-babel-import-util@^2.0.0:
+babel-import-util@^2.0.0, babel-import-util@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/babel-import-util/-/babel-import-util-2.1.1.tgz#0f4905fe899abfb8cd835dd52f3df1966d1ffbb0"
integrity sha512-3qBQWRjzP9NreSH/YrOEU1Lj5F60+pWSLP0kIdCWxjFHH7pX2YPHIxQ67el4gnMNfYoDxSDGcT0zpVlZ+gVtQA==
@@ -2921,6 +3055,13 @@ basic-auth@~2.0.1:
dependencies:
safe-buffer "5.1.2"
+better-path-resolve@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/better-path-resolve/-/better-path-resolve-1.0.0.tgz#13a35a1104cdd48a7b74bf8758f96a1ee613f99d"
+ integrity sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==
+ dependencies:
+ is-windows "^1.0.0"
+
big.js@^5.2.2:
version "5.2.2"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
@@ -4432,6 +4573,11 @@ cssesc@^3.0.0:
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
+csstype@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
+ integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
+
cyclist@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.2.tgz#673b5f233bf34d8e602b949429f8171d9121bea3"
@@ -4500,6 +4646,22 @@ decode-uri-component@^0.2.0:
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9"
integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==
+decorator-transforms@^1.0.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/decorator-transforms/-/decorator-transforms-1.2.1.tgz#d72e39b95c9e3d63465f82b148d021919e9d198f"
+ integrity sha512-UUtmyfdlHvYoX3VSG1w5rbvBQ2r5TX1JsE4hmKU9snleFymadA3VACjl6SRfi9YgBCSjBbfQvR1bs9PRW9yBKw==
+ dependencies:
+ "@babel/plugin-syntax-decorators" "^7.23.3"
+ babel-import-util "^2.0.1"
+
+decorator-transforms@^2.0.0, decorator-transforms@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/decorator-transforms/-/decorator-transforms-2.3.0.tgz#521d0617627e289dc47c2186787ac80390ee988a"
+ integrity sha512-jo8c1ss9yFPudHuYYcrJ9jpkDZIoi+lOGvt+Uyp9B+dz32i50icRMx9Bfa8hEt7TnX1FyKWKkjV+cUdT/ep2kA==
+ dependencies:
+ "@babel/plugin-syntax-decorators" "^7.23.3"
+ babel-import-util "^3.0.0"
+
deep-is@~0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
@@ -4640,6 +4802,13 @@ domain-browser@^1.1.1:
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
+dompurify@^3.2.4:
+ version "3.2.4"
+ resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.2.4.tgz#af5a5a11407524431456cf18836c55d13441cd8e"
+ integrity sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg==
+ optionalDependencies:
+ "@types/trusted-types" "^2.0.7"
+
dot-case@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751"
@@ -4714,6 +4883,13 @@ ember-ajax@^5.1.2:
ember-cli-babel "^7.5.0"
najax "^1.0.7"
+ember-assign-helper@^0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/ember-assign-helper/-/ember-assign-helper-0.5.0.tgz#73de4e2a96922162db78ab600038010d04773a89"
+ integrity sha512-swH7FqmqB5iSeoKlU6X41iqw5HQ+EdBDyFDXmwytTyUd5GRvfGfZUn2SMUUGdyvo5FxXJWqMJ0rBT//EcGC0+Q==
+ dependencies:
+ "@embroider/addon-shim" "^1.8.7"
+
ember-auto-import@^1.11.3:
version "1.12.2"
resolved "https://registry.yarnpkg.com/ember-auto-import/-/ember-auto-import-1.12.2.tgz#cc7298ee5c0654b0249267de68fb27a2861c3579"
@@ -4789,6 +4965,21 @@ ember-auto-import@^2.2.3, ember-auto-import@^2.4.0, ember-auto-import@^2.7.2:
typescript-memoize "^1.0.0-alpha.3"
walk-sync "^3.0.0"
+ember-basic-dropdown@^8.6.0:
+ version "8.6.0"
+ resolved "https://registry.yarnpkg.com/ember-basic-dropdown/-/ember-basic-dropdown-8.6.0.tgz#012f62b8aa12b587c8812a5b7a8b57800f68c59a"
+ integrity sha512-8OyhdDmaTKxVHKPny+4s79suzeDQGeahkbExvD8eYBzsiibXO/H15xGgmPlJ7WshdY/P44iQ01w85O90LaZRGQ==
+ dependencies:
+ "@embroider/addon-shim" "^1.9.0"
+ "@embroider/macros" "^1.16.10"
+ "@embroider/util" "^1.13.2"
+ decorator-transforms "^2.3.0"
+ ember-element-helper "^0.8.6"
+ ember-lifeline "^7.0.0"
+ ember-modifier "^4.2.0"
+ ember-style-modifier "^4.4.0"
+ ember-truth-helpers "^4.0.3"
+
ember-bootstrap@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/ember-bootstrap/-/ember-bootstrap-5.1.1.tgz#dfc9775eda7a8b1639445d6ec03baf9df7814681"
@@ -5331,6 +5522,17 @@ ember-concurrency@^2.1.2:
ember-compatibility-helpers "^1.2.0"
ember-destroyable-polyfill "^2.0.2"
+ember-concurrency@^4.0.3:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/ember-concurrency/-/ember-concurrency-4.0.3.tgz#7f8528c1a2f1ca438938f450e6f8c2b1bef98af1"
+ integrity sha512-deDJiB5OBYtYYOiVSt2qe5YBC8/vj1HwXPXtcw2SHijjMVL3i8ZBUmnHcaFr4RGsZJkGUr7Fg0zM45P9yUqKmQ==
+ dependencies:
+ "@babel/helper-module-imports" "^7.22.15"
+ "@babel/helper-plugin-utils" "^7.12.13"
+ "@babel/types" "^7.12.13"
+ "@embroider/addon-shim" "^1.8.7"
+ decorator-transforms "^1.0.1"
+
ember-data@~3.28.6:
version "3.28.13"
resolved "https://registry.yarnpkg.com/ember-data/-/ember-data-3.28.13.tgz#68668d84924453c2baeeb0cf7d25f75b2c07e8b9"
@@ -5378,6 +5580,14 @@ ember-element-helper@^0.6.0:
ember-cli-babel "^7.26.11"
ember-cli-htmlbars "^6.0.1"
+ember-element-helper@^0.8.6:
+ version "0.8.6"
+ resolved "https://registry.yarnpkg.com/ember-element-helper/-/ember-element-helper-0.8.6.tgz#564d63dbbb6130e4c69ff06b3bd8fbfb9cb4787a"
+ integrity sha512-WcbkJKgBZypRGwujeiPrQfZRhETVFLR0wvH2UxDaNBhLWncapt6KK+M/2i/eODoAQwgGxziejhXC6Cbqa9zA8g==
+ dependencies:
+ "@embroider/addon-shim" "^1.8.3"
+ "@embroider/util" "^1.0.0"
+
ember-export-application-global@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ember-export-application-global/-/ember-export-application-global-2.0.1.tgz#b120a70e322ab208defc9e2daebe8d0dfc2dcd46"
@@ -5424,6 +5634,13 @@ ember-inflector@^4.0.1:
dependencies:
ember-cli-babel "^7.26.11"
+ember-lifeline@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/ember-lifeline/-/ember-lifeline-7.0.0.tgz#46780c8f832b6c784ee4681b938a1e1437bfa676"
+ integrity sha512-2l51NzgH5vjN972zgbs+32rnXnnEFKB7qsSpJF+lBI4V5TG6DMy4SfowC72ZEuAtS58OVfwITbOO+RnM21EdpA==
+ dependencies:
+ "@embroider/addon-shim" "^1.6.0"
+
ember-load-initializers@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ember-load-initializers/-/ember-load-initializers-2.1.2.tgz#8a47a656c1f64f9b10cecdb4e22a9d52ad9c7efa"
@@ -5462,6 +5679,16 @@ ember-modifier@^3.1.0, ember-modifier@^3.2.7:
ember-cli-typescript "^5.0.0"
ember-compatibility-helpers "^1.2.5"
+"ember-modifier@^3.2.7 || ^4.0.0", ember-modifier@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/ember-modifier/-/ember-modifier-4.2.0.tgz#f99cb817b9b85c5188c63f853cd06aa62e8dde57"
+ integrity sha512-BJ48eTEGxD8J7+lofwVmee7xDgNDgpr5dd6+MSu4gk+I6xb35099RMNorXY5hjjwMJEyi/IRR6Yn3M7iJMz8Zw==
+ dependencies:
+ "@embroider/addon-shim" "^1.8.7"
+ decorator-transforms "^2.0.0"
+ ember-cli-normalize-entity-name "^1.0.0"
+ ember-cli-string-utils "^1.1.0"
+
ember-moment@^10.0.0:
version "10.0.1"
resolved "https://registry.yarnpkg.com/ember-moment/-/ember-moment-10.0.1.tgz#aecc2afec1aa214763069f9c7f1e755dbe567eb5"
@@ -5495,6 +5722,19 @@ ember-popper-modifier@^2.0.0:
ember-cli-htmlbars "^6.0.0"
ember-modifier "^3.1.0"
+ember-power-select@^8.7.0:
+ version "8.7.0"
+ resolved "https://registry.yarnpkg.com/ember-power-select/-/ember-power-select-8.7.0.tgz#5c103723f96c72f3939a2a37b50ce585fad9fc96"
+ integrity sha512-9T9M5QqgmAYORxxwiz4A9Hm8cZPWFsliIM8X2UVnQpO8Zd+oU/grIIF5MFkv2xTa9HGWCEvwnVRRUSPqFRBW7Q==
+ dependencies:
+ "@embroider/addon-shim" "^1.9.0"
+ "@embroider/util" "^1.13.2"
+ decorator-transforms "^2.3.0"
+ ember-assign-helper "^0.5.0"
+ ember-lifeline "^7.0.0"
+ ember-modifier "^4.2.0"
+ ember-truth-helpers "^4.0.3"
+
ember-qunit@^5.1.5:
version "5.1.5"
resolved "https://registry.yarnpkg.com/ember-qunit/-/ember-qunit-5.1.5.tgz#24a7850f052be24189ff597dfc31b923e684c444"
@@ -5588,6 +5828,16 @@ ember-style-modifier@^0.8.0:
ember-cli-babel "^7.26.6"
ember-modifier "^3.2.7"
+ember-style-modifier@^4.4.0:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/ember-style-modifier/-/ember-style-modifier-4.4.0.tgz#2d1fa6a35d41d88612277d7d149f1e569acaf8d3"
+ integrity sha512-gT1ckbhl1KSj5sWTo/8UChj98eZeE+mUmYoXw8VjwJgWP0wiTCibGZjVbC0WlIUd7umxuG61OQ/ivfF+sAiOEQ==
+ dependencies:
+ "@embroider/addon-shim" "^1.8.7"
+ csstype "^3.1.3"
+ decorator-transforms "^2.0.0"
+ ember-modifier "^3.2.7 || ^4.0.0"
+
ember-template-imports@^3.4.2:
version "3.4.2"
resolved "https://registry.yarnpkg.com/ember-template-imports/-/ember-template-imports-3.4.2.tgz#6cf7de7d4b8348a0fddf3aaec4947aa1211289e6"
@@ -7806,6 +8056,13 @@ is-string@^1.0.5, is-string@^1.0.7:
dependencies:
has-tostringtag "^1.0.0"
+is-subdir@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/is-subdir/-/is-subdir-1.2.0.tgz#b791cd28fab5202e91a08280d51d9d7254fd20d4"
+ integrity sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==
+ dependencies:
+ better-path-resolve "1.0.0"
+
is-symbol@^1.0.2, is-symbol@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c"
@@ -7844,7 +8101,7 @@ is-weakref@^1.0.2:
dependencies:
call-bind "^1.0.2"
-is-windows@^1.0.1, is-windows@^1.0.2:
+is-windows@^1.0.0, is-windows@^1.0.1, is-windows@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==
@@ -7975,6 +8232,11 @@ jsesc@^2.5.0, jsesc@^2.5.1:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
+jsesc@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d"
+ integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==
+
jsesc@~0.3.x:
version "0.3.0"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.3.0.tgz#1bf5ee63b4539fe2e26d0c1e99c240b97a457972"
@@ -9578,6 +9840,11 @@ pkg-dir@^4.1.0:
dependencies:
find-up "^4.0.0"
+pkg-entry-points@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/pkg-entry-points/-/pkg-entry-points-1.1.1.tgz#d5cd87f934e873bf73143ed1d0baf637e5f8fda4"
+ integrity sha512-BhZa7iaPmB4b3vKIACoppyUoYn8/sFs17VJJtzrzPZvEnN2nqrgg911tdL65lA2m1ml6UI3iPeYbZQ4VXpn1mA==
+
pkg-up@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f"
From 2470347680feb0f93f5aedc6af44ed9c046f3ab3 Mon Sep 17 00:00:00 2001
From: kudakwashe siziva <9620622+kaysiz@users.noreply.github.com>
Date: Thu, 8 May 2025 09:01:18 +0200
Subject: [PATCH 2/5] Client ID Registration: QA feedback (#241)
---
.../organizations/api-client-registration-form.hbs | 6 +++---
app/templates/organizations/api-client-id.hbs | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/app/components/organizations/api-client-registration-form.hbs b/app/components/organizations/api-client-registration-form.hbs
index 8e90d500..4f084405 100644
--- a/app/components/organizations/api-client-registration-form.hbs
+++ b/app/components/organizations/api-client-registration-form.hbs
@@ -4,12 +4,12 @@
Thank you for registering!
We have sent an email to {{this.email}} containing your client ID.
- This email was sent from support@ror.org with the subject "ROR API client ID".
+ This email was sent from api@ror.org with the subject "ROR API client ID".
If you do not receive this email within 15 minutes, check your spam/junk folder.
If you still cannot find this email, please contact
- support@ror.org .
+ api@ror.org .
{{else if this.showErrorMessage}}
@@ -17,7 +17,7 @@
Registration Error
Oh no, there was an error and we were not able to process your request for a ROR API client ID.
- Please contact support@ror.org for assistance.
+ Please contact api@ror.org for assistance.
ROR client IDs are not used for authentication or authorization, and are therefore not secret and can be sent as plain text.
We do not provide a way to recover or revoke a lost client ID. If you lose track of your client ID, please register a new client ID.
- For more information about ROR API client IDs, see https://ror.readme.io/XXXXX
- For additional help obtaining or using a ROR API client ID contact support@ror.org
+ For more information about ROR API client IDs, see https://ror.readme.io/docs/client-id
+ For additional help obtaining or using a ROR API client ID contact api@ror.org
From f86ba95ddd6fe329daffacac907fb98606cc23d2 Mon Sep 17 00:00:00 2001
From: kudakwashe siziva <9620622+kaysiz@users.noreply.github.com>
Date: Thu, 8 May 2025 15:43:47 +0200
Subject: [PATCH 3/5] Revert some changes for support email (#242)
---
app/templates/organizations/api-client-id.hbs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/templates/organizations/api-client-id.hbs b/app/templates/organizations/api-client-id.hbs
index c1c7d803..5cd284e6 100644
--- a/app/templates/organizations/api-client-id.hbs
+++ b/app/templates/organizations/api-client-id.hbs
@@ -13,7 +13,7 @@
ROR client IDs are not used for authentication or authorization, and are therefore not secret and can be sent as plain text.
We do not provide a way to recover or revoke a lost client ID. If you lose track of your client ID, please register a new client ID.
For more information about ROR API client IDs, see https://ror.readme.io/docs/client-id
- For additional help obtaining or using a ROR API client ID contact api@ror.org
+ For additional help obtaining or using a ROR API client ID contact support@ror.org
From 5599480070e288028ac59a2577ddef2f815210ef Mon Sep 17 00:00:00 2001
From: kudakwashe siziva <9620622+kaysiz@users.noreply.github.com>
Date: Thu, 8 May 2025 16:01:24 +0200
Subject: [PATCH 4/5] Revert changes to support email (#243)
* Revert some changes for support email
* Revert some changes for support email
---
.../organizations/api-client-registration-form.hbs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/components/organizations/api-client-registration-form.hbs b/app/components/organizations/api-client-registration-form.hbs
index 4f084405..3d57e27e 100644
--- a/app/components/organizations/api-client-registration-form.hbs
+++ b/app/components/organizations/api-client-registration-form.hbs
@@ -4,12 +4,12 @@
Thank you for registering!
We have sent an email to {{this.email}} containing your client ID.
- This email was sent from api@ror.org with the subject "ROR API client ID".
+ This email was sent from api@ror.org with the subject "ROR API client ID".
If you do not receive this email within 15 minutes, check your spam/junk folder.
If you still cannot find this email, please contact
- api@ror.org .
+ support@ror.org .
{{else if this.showErrorMessage}}
@@ -17,7 +17,7 @@
Registration Error
Oh no, there was an error and we were not able to process your request for a ROR API client ID.
- Please contact api@ror.org for assistance.
+ Please contact support@ror.org for assistance.
Date: Thu, 3 Jul 2025 17:26:02 -0700
Subject: [PATCH 5/5] Used fixed name order in organization-item.js
---
app/components/organization-item.js | 41 ++++++++++++++++++-----------
1 file changed, 26 insertions(+), 15 deletions(-)
diff --git a/app/components/organization-item.js b/app/components/organization-item.js
index 46f317f8..cb40489d 100644
--- a/app/components/organization-item.js
+++ b/app/components/organization-item.js
@@ -33,32 +33,43 @@ export default Component.extend({
return formattedRelationships
},
- convertOtherNames(names){
- const groupedNames = names.reduce((result, name) => {
+ convertOtherNames(names) {
+ const nameOrder = ['label', 'alias', 'acronym'];
+
+ const initialGroupedNames = names.reduce((result, name) => {
if (name.types.includes("ror_display")) {
- return result;
+ return result;
}
-
const type = name.types.includes("label") ? "label" : name.types[0];
result[type] = result[type] || [];
+
+ if (name.lang && !name.value.includes(`(${name.lang})`)) {
+ name.value = `${name.value} (${name.lang})`;
+ }
result[type].push(name);
-
return result;
}, {});
- for (let key in groupedNames) {
- if (groupedNames[key]) {
- groupedNames[key].forEach((item) => {
- if (item.lang && !item.value.includes(`(${item.lang})`)) {
- item.value = `${item.value} (${item.lang})`;
- }
- })
+ const orderedGroupedNames = {};
+ const orderedValues = [];
+
+ nameOrder.forEach(type => {
+ if (initialGroupedNames[type]) {
+ orderedGroupedNames[type] = initialGroupedNames[type];
+
+ initialGroupedNames[type].forEach(item => {
+ orderedValues.push(item.value);
+ });
}
- }
+ });
- const values = Object.values(groupedNames).flat().map(item => item.value).join(', ');
+ const valuesString = orderedValues.join(', ');
- return {values: values, groupedNames: groupedNames, groupedNamesCount: Object.keys(groupedNames).length};
+ return {
+ values: valuesString,
+ groupedNames: orderedGroupedNames,
+ groupedNamesCount: Object.keys(orderedGroupedNames).length
+ };
},
getName(names) {