From 9ecf05369fa449a6dc1d06d985db74f47e5c4117 Mon Sep 17 00:00:00 2001 From: Duane Nykamp Date: Tue, 13 Aug 2024 21:15:47 -0500 Subject: [PATCH 1/9] allow test logins in dev mode --- server/package.json | 2 +- server/src/index.ts | 64 ++++++++++++++++++++++++++++++++-------- server/src/model.test.ts | 2 +- server/src/model.ts | 17 ++++++++++- 4 files changed, 70 insertions(+), 15 deletions(-) diff --git a/server/package.json b/server/package.json index c0aec26cd..95f18d5a8 100644 --- a/server/package.json +++ b/server/package.json @@ -6,7 +6,7 @@ "scripts": { "test": "vitest", "dev": "npx nodemon src/index.ts", - "build": "npx tsc", + "build": "npx tsc && cp src/signin_email.html dist/src/", "start": "node dist/src/index.js" }, "keywords": [], diff --git a/server/src/index.ts b/server/src/index.ts index 2416fd959..04dcf236f 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -19,6 +19,7 @@ import { getAllRecentPublicActivities, getIsAdmin, getUserInfo, + getUserInfoFromEmail, updateDoc, searchSharedContent, updateContent, @@ -245,7 +246,7 @@ passport.serializeUser(async (_req, user: any, done) => { }); } - return done(undefined, u.email); + return done(undefined, u.userId); } else if (user.provider === "google") { let email = user.id + "@google.com"; if (user.emails[0].verified) { @@ -257,20 +258,41 @@ passport.serializeUser(async (_req, user: any, done) => { firstNames: user.name.givenName, lastNames: user.name.familyName, }); - return done(undefined, u.email); + return done(undefined, u.userId); } else if (user.uuid) { + let email = user.uuid + "@anonymous.doenet.org"; + let lastNames = ""; + let firstNames: string | null = null; + let isAnonymous = true; + + if ( + process.env.ALLOW_TEST_LOGIN && + process.env.ALLOW_TEST_LOGIN.toLocaleLowerCase() !== "false" + ) { + if (req.body.email) { + email = req.body.email; + } + if (req.body.firstNames) { + firstNames = req.body.firstNames; + } + if (req.body.lastNames) { + lastNames = req.body.lastNames; + } + isAnonymous = false; + } + const u = await findOrCreateUser({ - email: user.uuid + "@anonymous.doenet.org", - lastNames: "", - firstNames: null, - isAnonymous: true, + email, + lastNames, + firstNames, + isAnonymous, }); - return done(undefined, u.email); + return done(undefined, u.userId); } }); -passport.deserializeUser(async (id: string, done) => { - const u = await getUserInfo(id); +passport.deserializeUser(async (userId: number, done) => { + const u = await getUserInfo(userId); done(null, u); }); @@ -321,6 +343,19 @@ app.get( }, ); +if ( + process.env.ALLOW_TEST_LOGIN && + process.env.ALLOW_TEST_LOGIN.toLocaleLowerCase() !== "false" +) { + app.post( + "/api/login/createOrLoginAsTest", + passport.authenticate("anonymId"), + (req: Request, res: Response) => { + res.send({}); + }, + ); +} + app.get( "/api/auth/google", passport.authenticate("google", { scope: ["profile", "email"] }), @@ -347,7 +382,9 @@ app.get( userPrimaryKey: "email", }), async (req: Request, res: Response) => { - const user = await getUserInfo((req.user as { email: string }).email); + const user = await getUserInfoFromEmail( + (req.user as { email: string }).email, + ); res.send({ user }); }, ); @@ -372,7 +409,7 @@ app.get( const signedIn = req.user ? true : false; if (signedIn) { try { - const user = await getUserInfo(req.user.email); + let user = await getUserInfo(req.user.userId); res.send({ user }); } catch (e) { next(e); @@ -1228,7 +1265,10 @@ app.get( }); res.send(data); } catch (e) { - if (e instanceof Prisma.PrismaClientKnownRequestError) { + if ( + e instanceof Prisma.PrismaClientKnownRequestError && + e.code === "P2025" + ) { res.sendStatus(404); } else { next(e); diff --git a/server/src/model.test.ts b/server/src/model.test.ts index 5bf9b9891..7c6b489b8 100644 --- a/server/src/model.test.ts +++ b/server/src/model.test.ts @@ -136,7 +136,7 @@ test("Update user name", async () => { expect(user.firstNames).eq("New"); expect(user.lastNames).eq("Name"); - const userInfo = await getUserInfo(user.email); + const userInfo = await getUserInfo(user.userId); expect(userInfo.firstNames).eq("New"); expect(userInfo.lastNames).eq("Name"); }); diff --git a/server/src/model.ts b/server/src/model.ts index 672ce5704..95f72e358 100644 --- a/server/src/model.ts +++ b/server/src/model.ts @@ -2088,7 +2088,22 @@ export async function findOrCreateUser({ return user; } -export async function getUserInfo(email: string) { +export async function getUserInfo(userId: number) { + const user = await prisma.users.findUniqueOrThrow({ + where: { userId }, + select: { + userId: true, + email: true, + firstNames: true, + lastNames: true, + isAnonymous: true, + isAdmin: true, + }, + }); + return user; +} + +export async function getUserInfoFromEmail(email: string) { const user = await prisma.users.findUniqueOrThrow({ where: { email }, select: { From 690fec5f9c586aaef6049d9aa2a1bee0a70ecb43 Mon Sep 17 00:00:00 2001 From: Duane Nykamp Date: Tue, 13 Aug 2024 21:38:57 -0500 Subject: [PATCH 2/9] start cypress create and share folder test --- client/cypress.config.js | 18 +- .../cypress/e2e/Folders/createFolders.cy.js | 81 +++++ client/cypress/support/commands.js | 303 +----------------- client/package-lock.json | 235 +++++++------- client/package.json | 1 + .../src/Tools/_framework/Paths/Activities.tsx | 3 + .../Tools/_framework/Paths/ActivityEditor.tsx | 2 +- .../_framework/ToolPanels/ShareDrawer.tsx | 50 +-- .../_framework/ToolPanels/ShareSettings.tsx | 2 + client/src/Widgets/ActivityTable.tsx | 2 + client/src/Widgets/ContentCard.tsx | 1 + 11 files changed, 274 insertions(+), 424 deletions(-) create mode 100644 client/cypress/e2e/Folders/createFolders.cy.js diff --git a/client/cypress.config.js b/client/cypress.config.js index b11ce303d..efd4be7dc 100644 --- a/client/cypress.config.js +++ b/client/cypress.config.js @@ -22,7 +22,7 @@ import { defineConfig } from "cypress"; export default defineConfig({ numTestsKeptInMemory: 20, - defaultCommandTimeout: 30000, + defaultCommandTimeout: 10000, e2e: { setupNodeEvents(on, config) { on("before:browser:launch", (browser = {}, launchOptions) => { @@ -41,12 +41,12 @@ export default defineConfig({ baseUrl: "http://localhost:8000", }, - env: { - db: { - host: "localhost", - user: "root", - password: "helloworld", - database: "doenet_local", - }, - }, + // env: { + // db: { + // host: "localhost", + // user: "root", + // password: "helloworld", + // database: "doenet_local", + // }, + // }, }); diff --git a/client/cypress/e2e/Folders/createFolders.cy.js b/client/cypress/e2e/Folders/createFolders.cy.js new file mode 100644 index 000000000..b8f0ae2f0 --- /dev/null +++ b/client/cypress/e2e/Folders/createFolders.cy.js @@ -0,0 +1,81 @@ +describe("Create Folders Tests", function () { + before(() => {}); + + beforeEach(() => {}); + + // TODO: this test is unfinished, but waiting until + // the folder UI redesign + it("create and share folder", () => { + let code = Date.now().toString(); + const scrappyEmail = `scrappy${code}@doo`; + const scoobyEmail = `scooby${code}@doo`; + + // create scrappy account so can share content with it + cy.loginAsTestUser({ + email: scrappyEmail, + firstNames: "Scrappy", + lastNames: "Doo", + }); + + cy.loginAsTestUser({ + email: scoobyEmail, + firstNames: "Scooby", + lastNames: "Doo", + }); + + cy.visit("/"); + + cy.get('[data-test="Activities"]').click(); + cy.get('[data-test="New Button"]').click(); + cy.get('[data-test="Add Folder Button"]').click(); + + cy.get('[data-test="Editable Title"]').type("My new folder{enter}"); + cy.get('[data-test="Activity Link"]').click(); + + cy.get('[data-test="Folder Heading"]').should( + "contain.text", + "My new folder", + ); + + cy.get('[data-test="New Button"]').click(); + cy.get('[data-test="Add Folder Button"]').click(); + cy.get('[data-test="Editable Title"]').type(`Private folder${code}{enter}`); + + cy.get('[data-test="New Button"]').click(); + cy.get('[data-test="Add Folder Button"]').click(); + cy.get('[data-test="Editable Title"]') + .eq(1) + .type(`Shared folder${code}{enter}`); + + cy.get('[data-test="Card Menu Button"]').eq(1).click(); + cy.get('[data-test="Share Menu Item"]').eq(1).click({ force: true }); + cy.get('[data-test="Email address"]').type(`${scrappyEmail}{enter}`); + cy.get('[data-test="Status message"]').should("contain.text", scrappyEmail); + cy.get('[data-test="Close Share Drawer Button"]').click(); + + cy.get('[data-test="Activity Link"]').eq(1).click(); + cy.get('[data-test="Folder Heading"]').should( + "contain.text", + `Shared folder${code}`, + ); + + cy.get('[data-test="New Button"]').click(); + cy.get('[data-test="Add Activity Button"]').click(); + + cy.get('[data-test="Activity Name Editable"]').type( + "Shared activity{enter}", + ); + + cy.iframe().find(".cm-editor").type(`Hello${code}!{enter}`); + cy.iframe().find('[data-test="Viewer Update Button"]').click(); + cy.iframe().find(".doenet-viewer").should("contain.text", `Hello${code}!`); + + cy.loginAsTestUser({ + email: scrappyEmail, + }); + cy.visit("/"); + + cy.get('[data-test="Community"]').click(); + cy.get('[data-test="Search"]').type(`folder${code}{enter}`); + }); +}); diff --git a/client/cypress/support/commands.js b/client/cypress/support/commands.js index 3fbb6aa36..7a4fe336c 100644 --- a/client/cypress/support/commands.js +++ b/client/cypress/support/commands.js @@ -26,295 +26,24 @@ import "cypress-wait-until"; import "cypress-file-upload"; +import "cypress-iframe"; Cypress.Commands.add( - "createUserRole", - ({ courseId, roleId, label = "no label" }) => { - cy.task( - "queryDb", - ` - SELECT roleId - FROM course_role - WHERE courseId="${courseId}" - AND roleId="${roleId}"`, - ).then((result) => { - //Only insert if not a duplicate - if (result.length == 0) { - cy.log("here", result.length); - cy.task( - "queryDb", - ` - INSERT INTO course_role - SET courseId="${courseId}", roleId="${roleId}", label="${label}"`, - ); - } + "loginAsTestUser", + ({ email, firstNames, lastNames } = {}) => { + if (!email) { + const code = Date.now().toString(); + email = `test${code}@doenet.org`; + firstNames = `Test`; + lastNames = `User${code}`; + } + + cy.session(email, () => { + cy.request({ + method: "POST", + url: "/api/login/createOrLoginAsTest", + body: { email, firstNames, lastNames }, + }); }); }, ); - -Cypress.Commands.add("updateRolePerm", ({ roleId, permName, newValue }) => { - cy.task( - "queryDb", - ` - UPDATE course_role - SET ${permName}="${newValue}" - WHERE roleId="${roleId}" - `, - ); -}); - -Cypress.Commands.add("setUserRole", ({ userId, courseId, roleId }) => { - cy.task( - "queryDb", - ` - UPDATE course_user - SET roleId="${roleId}" - WHERE userId="${userId}" - AND courseId="${courseId}" - `, - ); -}); - -Cypress.Commands.add("setUserUpload", ({ userId, newValue = "1" }) => { - cy.task( - "queryDb", - ` - UPDATE user - SET canUpload="${newValue}" - WHERE userId="${userId}" - `, - ); -}); - -Cypress.Commands.add( - "signin", - ({ userId, firstName = "first", lastName = "last" }) => { - cy.request( - `/cyapi/cypressAutoSignin.php?userId=${userId}&firstName=${firstName}&lastName=${lastName}`, - ); - // .then((resp)=>{ - // cy.log("signin",resp.body) - // }) - }, -); - -Cypress.Commands.add( - "saveDoenetML", - ({ doenetML, pageId, courseId, lastKnownCid }) => { - cy.request("POST", "/api/saveDoenetML.php", { - doenetML, - pageId, - courseId, - lastKnownCid, - backup: false, - }).then((resp) => { - cy.log("saveDoenetML", resp.body); - }); - }, -); - -Cypress.Commands.add("clearEvents", ({ doenetId }) => { - cy.request(`/cyapi/cypressClearEvents.php?doenetId=${doenetId}`); - // .then((resp)=>{ - // cy.log(resp.body) - // }) -}); - -Cypress.Commands.add("clearAllOfAUsersCoursesAndItems", ({ userId }) => { - cy.request(`/cyapi/cypressAllOfAUsersCoursesAndItems.php?userId=${userId}`); - // .then((resp)=>{ - // cy.log(resp.body) - // }) -}); - -Cypress.Commands.add("clearAllOfAUsersActivities", ({ userId }) => { - cy.request(`/cyapi/clearAllOfAUsersActivities.php?userId=${userId}`); - // .then((resp)=>{ - // cy.log(resp.body) - // }) -}); - -Cypress.Commands.add("clearCoursePeople", ({ courseId }) => { - cy.request(`/cyapi/cypressClearCoursePeople.php?courseId=${courseId}`); - // .then((resp)=>{ - // cy.log(resp.body) - // }) -}); - -Cypress.Commands.add( - "createCourse", - ({ userId, courseId, studentUserId, label }) => { - cy.request("POST", `/cyapi/cypressCreateCourse.php`, { - userId, - courseId, - studentUserId, - label, - }); - // .then((resp)=>{ - // cy.log(resp.body) - // }) - }, -); - -Cypress.Commands.add("assertValueCopiedToClipboard", (value) => { - cy.window().then((win) => { - win.navigator.clipboard.readText().then((text) => { - expect(text).to.eq(value); - }); - }); -}); - -Cypress.Commands.add("deleteCourseDBRows", ({ courseId }) => { - cy.task( - "queryDb", - ` - DELETE FROM course_user - WHERE courseId="${courseId}" - `, - ); - cy.task( - "queryDb", - ` - DELETE FROM course_content - WHERE courseId="${courseId}" - `, - ); - cy.task( - "queryDb", - ` - DELETE FROM course_role - WHERE courseId="${courseId}" - `, - ); - cy.task( - "queryDb", - ` - DELETE FROM course - WHERE courseId="${courseId}" - `, - ); -}); - -Cypress.Commands.add("deleteCourse", ({ label, courseId }) => { - if (courseId) { - cy.task( - "queryDb", - ` - UPDATE course - SET isDeleted = TRUE - WHERE courseId="${courseId}" - `, - ); - } else if (label) { - cy.task( - "queryDb", - ` - UPDATE course - SET isDeleted = TRUE - WHERE label="${label}" - `, - ); - } -}); - -Cypress.Commands.add("deleteActivity", ({ userId, label }) => { - cy.task( - "queryDb", - `DELETE - FROM course_content - WHERE label = '${label}' - `, - ); - // cy.task( - // "queryDb", - // `DELETE cc - // FROM course_content AS cc - // LEFT JOIN course AS c - // ON cc.courseId = c.courseId - // WHERE cc.label = '${label}' - // AND c.portfolioCourseForUserId = '${userId}' - // `, - // ); -}); - -Cypress.Commands.add( - "createActivity", - ({ - courseId, - doenetId, - parentDoenetId, - pageDoenetId, - doenetML = "", - label = "Cypress Activity", - }) => { - cy.request("POST", `/cyapi/cypressCreateActivity.php`, { - courseId, - doenetId, - parentDoenetId, - pageDoenetId, - doenetML, - label, - }); - }, -); - -Cypress.Commands.add( - "updateActivitySettings", - ({ courseId, doenetId, activitySettings }) => { - cy.request("POST", `/cyapi/cypressUpdateActivitySettings.php`, { - courseId, - doenetId, - activitySettings, - }); - // .then((resp)=>{ - // cy.log(resp.body) - // }) - }, -); - -Cypress.Commands.add( - "createMultipageActivity", - ({ - courseId, - doenetId, - parentDoenetId, - pageDoenetId1, - pageDoenetId2, - pageDoenetId3, - pageDoenetId4, - doenetML1, - doenetML2, - doenetML3, - doenetML4, - shuffleDoenetId, - shufflePages, - }) => { - cy.log( - courseId, - doenetId, - parentDoenetId, - pageDoenetId1, - pageDoenetId2, - pageDoenetId3, - pageDoenetId4, - ); - cy.request("POST", `/cyapi/cypressCreateMultipageActivity.php`, { - courseId, - doenetId, - parentDoenetId, - pageDoenetId1, - pageDoenetId2, - pageDoenetId3, - pageDoenetId4, - doenetML1, - doenetML2, - doenetML3, - doenetML4, - shuffleDoenetId, - shufflePages, - }); - // .then((resp)=>{ - // cy.log(resp.body) - // }) - }, -); diff --git a/client/package-lock.json b/client/package-lock.json index 3b237ae9c..bf122bddf 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -53,6 +53,7 @@ "@vitejs/plugin-react": "^4.3.1", "@web/test-runner": "^0.18.2", "chai": "^5.1.1", + "cypress-iframe": "^1.0.1", "esbuild": "^0.14.54", "eslint": "^8.14.0", "eslint-config-prettier": "^8.2.0", @@ -1767,7 +1768,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.1.tgz", "integrity": "sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==", - "optional": true, + "devOptional": true, "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -1796,7 +1797,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "optional": true, + "devOptional": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -1810,7 +1811,7 @@ "version": "6.10.4", "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz", "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==", - "optional": true, + "devOptional": true, "dependencies": { "side-channel": "^1.0.4" }, @@ -1825,7 +1826,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", - "optional": true, + "devOptional": true, "dependencies": { "debug": "^3.1.0", "lodash.once": "^4.1.1" @@ -1835,7 +1836,7 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "optional": true, + "devOptional": true, "dependencies": { "ms": "^2.1.1" } @@ -3469,6 +3470,17 @@ "@types/node": "*" } }, + "node_modules/@types/cypress": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/cypress/-/cypress-1.1.3.tgz", + "integrity": "sha512-OXe0Gw8LeCflkG1oPgFpyrYWJmEKqYncBsD/J0r17r0ETx/TnIGDNLwXt/pFYSYuYTpzcq1q3g62M9DrfsBL4g==", + "deprecated": "This is a stub types definition for cypress (https://cypress.io). cypress provides its own type definitions, so you don't need @types/cypress installed!", + "dev": true, + "peer": true, + "dependencies": { + "cypress": "*" + } + }, "node_modules/@types/d3-array": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", @@ -3772,13 +3784,13 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", - "optional": true + "devOptional": true }, "node_modules/@types/sizzle": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz", "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==", - "optional": true + "devOptional": true }, "node_modules/@types/ws": { "version": "7.4.7", @@ -4502,7 +4514,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "optional": true, + "devOptional": true, "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -4541,7 +4553,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "optional": true, + "devOptional": true, "engines": { "node": ">=6" } @@ -4598,6 +4610,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "devOptional": true, "funding": [ { "type": "github", @@ -4611,8 +4624,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "optional": true + ] }, "node_modules/argparse": { "version": "2.0.1", @@ -4856,7 +4868,7 @@ "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "optional": true, + "devOptional": true, "dependencies": { "safer-buffer": "~2.1.0" } @@ -4865,7 +4877,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "optional": true, + "devOptional": true, "engines": { "node": ">=0.8" } @@ -4918,7 +4930,7 @@ "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "optional": true + "devOptional": true }, "node_modules/async-mutex": { "version": "0.4.0", @@ -4938,7 +4950,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "optional": true, + "devOptional": true, "engines": { "node": ">= 4.0.0" } @@ -4981,7 +4993,7 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "optional": true, + "devOptional": true, "engines": { "node": "*" } @@ -4999,7 +5011,7 @@ "version": "1.13.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==", - "optional": true + "devOptional": true }, "node_modules/axe-core": { "version": "4.9.1", @@ -5525,7 +5537,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "optional": true, + "devOptional": true, "dependencies": { "tweetnacl": "^0.14.3" } @@ -5557,13 +5569,13 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", - "optional": true + "devOptional": true }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "optional": true + "devOptional": true }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -5724,7 +5736,7 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", - "optional": true, + "devOptional": true, "engines": { "node": ">=6" } @@ -5804,7 +5816,7 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "optional": true + "devOptional": true }, "node_modules/chai": { "version": "5.1.1", @@ -5941,7 +5953,7 @@ "version": "2.24.0", "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", - "optional": true, + "devOptional": true, "engines": { "node": ">= 0.8.0" } @@ -6006,13 +6018,13 @@ "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "devOptional": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/sibiraj-s" } ], - "optional": true, "engines": { "node": ">=8" } @@ -6058,7 +6070,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "optional": true, + "devOptional": true, "engines": { "node": ">=6" } @@ -6079,7 +6091,7 @@ "version": "0.6.5", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", - "optional": true, + "devOptional": true, "dependencies": { "string-width": "^4.2.0" }, @@ -6094,7 +6106,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "optional": true, + "devOptional": true, "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" @@ -6241,7 +6253,7 @@ "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "optional": true + "devOptional": true }, "node_modules/combined-stream": { "version": "1.0.8", @@ -6314,7 +6326,7 @@ "version": "1.8.2", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "optional": true, + "devOptional": true, "engines": { "node": ">=4.0.0" } @@ -6441,7 +6453,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "optional": true + "devOptional": true }, "node_modules/cosmiconfig": { "version": "7.1.0", @@ -6524,8 +6536,8 @@ "version": "13.13.2", "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.13.2.tgz", "integrity": "sha512-PvJQU33933NvS1StfzEb8/mu2kMy4dABwCF+yd5Bi7Qly1HOVf+Bufrygee/tlmty/6j5lX+KIi8j9Q3JUMbhA==", + "devOptional": true, "hasInstallScript": true, - "optional": true, "dependencies": { "@cypress/request": "^3.0.1", "@cypress/xvfb": "^1.2.4", @@ -6589,6 +6601,15 @@ "cypress": ">3.0.0" } }, + "node_modules/cypress-iframe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cypress-iframe/-/cypress-iframe-1.0.1.tgz", + "integrity": "sha512-Ne+xkZmWMhfq3x6wbfzK/SzsVTCrJru3R3cLXsoSAZyfUtJDamXyaIieHXeea3pQDXF4wE2w4iUuvCYHhoD31g==", + "dev": true, + "peerDependencies": { + "@types/cypress": "^1.1.0" + } + }, "node_modules/cypress-multi-reporters": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/cypress-multi-reporters/-/cypress-multi-reporters-1.6.4.tgz", @@ -6904,7 +6925,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "optional": true, + "devOptional": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -6919,7 +6940,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "optional": true, + "devOptional": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -6935,7 +6956,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "optional": true, + "devOptional": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -6947,7 +6968,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "optional": true, + "devOptional": true, "dependencies": { "color-name": "~1.1.4" }, @@ -6959,13 +6980,13 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "optional": true + "devOptional": true }, "node_modules/cypress/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==", - "optional": true, + "devOptional": true, "engines": { "node": ">=8" } @@ -6974,13 +6995,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", - "optional": true + "devOptional": true }, "node_modules/cypress/node_modules/semver": { "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "optional": true, + "devOptional": true, "bin": { "semver": "bin/semver.js" }, @@ -6992,7 +7013,7 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "optional": true, + "devOptional": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -7123,7 +7144,7 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "optional": true, + "devOptional": true, "dependencies": { "assert-plus": "^1.0.0" }, @@ -7195,7 +7216,7 @@ "version": "1.11.11", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==", - "optional": true + "devOptional": true }, "node_modules/debounce": { "version": "1.2.1", @@ -7537,7 +7558,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "optional": true, + "devOptional": true, "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -7582,7 +7603,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "optional": true, + "devOptional": true, "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" @@ -8801,7 +8822,7 @@ "version": "6.4.7", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", - "optional": true + "devOptional": true }, "node_modules/eventemitter3": { "version": "4.0.7", @@ -8812,7 +8833,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "optional": true, + "devOptional": true, "dependencies": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", @@ -8835,7 +8856,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "optional": true, + "devOptional": true, "dependencies": { "pump": "^3.0.0" }, @@ -8850,7 +8871,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", - "optional": true, + "devOptional": true, "dependencies": { "pify": "^2.2.0" }, @@ -8934,7 +8955,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "optional": true + "devOptional": true }, "node_modules/extend-shallow": { "version": "3.0.2", @@ -9035,10 +9056,10 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "devOptional": true, "engines": [ "node >=0.6.0" - ], - "optional": true + ] }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -9110,7 +9131,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "optional": true, + "devOptional": true, "dependencies": { "escape-string-regexp": "^1.0.5" }, @@ -9125,7 +9146,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "optional": true, + "devOptional": true, "engines": { "node": ">=0.8.0" } @@ -9278,7 +9299,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "optional": true, + "devOptional": true, "engines": { "node": "*" } @@ -9370,7 +9391,7 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "optional": true, + "devOptional": true, "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -9571,7 +9592,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", - "optional": true, + "devOptional": true, "dependencies": { "async": "^3.2.0" } @@ -9580,7 +9601,7 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "optional": true, + "devOptional": true, "dependencies": { "assert-plus": "^1.0.0" } @@ -9635,7 +9656,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "optional": true, + "devOptional": true, "dependencies": { "ini": "2.0.0" }, @@ -9980,7 +10001,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", - "optional": true, + "devOptional": true, "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^2.0.2", @@ -10007,7 +10028,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "optional": true, + "devOptional": true, "engines": { "node": ">=8.12.0" } @@ -10080,7 +10101,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "optional": true, + "devOptional": true, "engines": { "node": ">=8" } @@ -10113,7 +10134,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "optional": true, + "devOptional": true, "engines": { "node": ">=10" } @@ -10351,7 +10372,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "optional": true, + "devOptional": true, "dependencies": { "ci-info": "^3.2.0" }, @@ -10511,7 +10532,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "optional": true, + "devOptional": true, "dependencies": { "global-dirs": "^3.0.0", "is-path-inside": "^3.0.2" @@ -10748,13 +10769,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "optional": true + "devOptional": true }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "optional": true, + "devOptional": true, "engines": { "node": ">=10" }, @@ -10857,7 +10878,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "optional": true + "devOptional": true }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", @@ -10998,7 +11019,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "optional": true + "devOptional": true }, "node_modules/jsesc": { "version": "2.5.2", @@ -11026,7 +11047,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "optional": true + "devOptional": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -11044,7 +11065,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "optional": true + "devOptional": true }, "node_modules/json5": { "version": "2.2.3", @@ -11073,10 +11094,10 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "devOptional": true, "engines": [ "node >=0.6.0" ], - "optional": true, "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -11248,7 +11269,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", - "optional": true, + "devOptional": true, "engines": { "node": "> 0.8" } @@ -11300,7 +11321,7 @@ "version": "3.14.0", "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", - "optional": true, + "devOptional": true, "dependencies": { "cli-truncate": "^2.1.0", "colorette": "^2.0.16", @@ -11375,13 +11396,13 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", - "optional": true + "devOptional": true }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "optional": true, + "devOptional": true, "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -11397,7 +11418,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "optional": true, + "devOptional": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -11412,7 +11433,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "optional": true, + "devOptional": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -11428,7 +11449,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "optional": true, + "devOptional": true, "dependencies": { "color-name": "~1.1.4" }, @@ -11440,13 +11461,13 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "optional": true + "devOptional": true }, "node_modules/log-symbols/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==", - "optional": true, + "devOptional": true, "engines": { "node": ">=8" } @@ -11455,7 +11476,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "optional": true, + "devOptional": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -12446,7 +12467,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", - "optional": true + "devOptional": true }, "node_modules/p-event": { "version": "4.2.0", @@ -12506,7 +12527,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "optional": true, + "devOptional": true, "dependencies": { "aggregate-error": "^3.0.0" }, @@ -12688,7 +12709,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "optional": true + "devOptional": true }, "node_modules/picocolors": { "version": "1.0.1", @@ -12710,7 +12731,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "optional": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -12861,7 +12882,7 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "optional": true, + "devOptional": true, "engines": { "node": ">=6" }, @@ -12927,7 +12948,7 @@ "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "optional": true, + "devOptional": true, "engines": { "node": ">= 0.6.0" } @@ -12993,7 +13014,7 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "optional": true + "devOptional": true }, "node_modules/pump": { "version": "3.0.0", @@ -13075,7 +13096,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "optional": true + "devOptional": true }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -13660,7 +13681,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", - "optional": true, + "devOptional": true, "dependencies": { "throttleit": "^1.0.0" } @@ -13800,7 +13821,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "optional": true + "devOptional": true }, "node_modules/rimraf": { "version": "3.0.2", @@ -13939,7 +13960,7 @@ "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "optional": true, + "devOptional": true, "dependencies": { "tslib": "^2.1.0" } @@ -14206,7 +14227,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "optional": true, + "devOptional": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -14220,7 +14241,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "optional": true, + "devOptional": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -14235,7 +14256,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "optional": true, + "devOptional": true, "dependencies": { "color-name": "~1.1.4" }, @@ -14247,7 +14268,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "optional": true + "devOptional": true }, "node_modules/smart-buffer": { "version": "4.2.0", @@ -14558,7 +14579,7 @@ "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "optional": true, + "devOptional": true, "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -14984,7 +15005,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", - "optional": true, + "devOptional": true, "funding": { "url": "https://github.com/sponsors/sindresorhus" } @@ -15009,7 +15030,7 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", - "optional": true, + "devOptional": true, "engines": { "node": ">=14.14" } @@ -15088,7 +15109,7 @@ "version": "4.1.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "optional": true, + "devOptional": true, "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -15103,7 +15124,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "optional": true, + "devOptional": true, "engines": { "node": ">= 4.0.0" } @@ -15162,7 +15183,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "optional": true, + "devOptional": true, "dependencies": { "safe-buffer": "^5.0.1" }, @@ -15174,7 +15195,7 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "optional": true + "devOptional": true }, "node_modules/type-check": { "version": "0.4.0", @@ -15431,7 +15452,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "optional": true, + "devOptional": true, "engines": { "node": ">=8" } @@ -15484,7 +15505,7 @@ "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "optional": true, + "devOptional": true, "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -15562,7 +15583,7 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "optional": true, + "devOptional": true, "bin": { "uuid": "dist/bin/uuid" } @@ -15603,10 +15624,10 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "devOptional": true, "engines": [ "node >=0.6.0" ], - "optional": true, "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", diff --git a/client/package.json b/client/package.json index f3e9efdff..74f2e09c8 100644 --- a/client/package.json +++ b/client/package.json @@ -74,6 +74,7 @@ "@vitejs/plugin-react": "^4.3.1", "@web/test-runner": "^0.18.2", "chai": "^5.1.1", + "cypress-iframe": "^1.0.1", "esbuild": "^0.14.54", "eslint": "^8.14.0", "eslint-config-prettier": "^8.2.0", diff --git a/client/src/Tools/_framework/Paths/Activities.tsx b/client/src/Tools/_framework/Paths/Activities.tsx index 3dfd675f9..c7ec1b106 100644 --- a/client/src/Tools/_framework/Paths/Activities.tsx +++ b/client/src/Tools/_framework/Paths/Activities.tsx @@ -586,11 +586,13 @@ export function Activities() { size="sm" colorScheme="blue" hidden={searchOpen || haveQuery} + data-test="New Button" > {haveContentSpinner ? : "New"} { setHaveContentSpinner(true); //Create an activity and redirect to the editor for it @@ -611,6 +613,7 @@ export function Activities() { Activity { setHaveContentSpinner(true); fetcher.submit( diff --git a/client/src/Tools/_framework/Paths/ActivityEditor.tsx b/client/src/Tools/_framework/Paths/ActivityEditor.tsx index 46142a713..6dfea5337 100644 --- a/client/src/Tools/_framework/Paths/ActivityEditor.tsx +++ b/client/src/Tools/_framework/Paths/ActivityEditor.tsx @@ -660,7 +660,7 @@ export function ActivityEditor() { { textEditorDoenetML.current = newDoenetML; diff --git a/client/src/Tools/_framework/ToolPanels/ShareDrawer.tsx b/client/src/Tools/_framework/ToolPanels/ShareDrawer.tsx index 1f7982612..26091001b 100644 --- a/client/src/Tools/_framework/ToolPanels/ShareDrawer.tsx +++ b/client/src/Tools/_framework/ToolPanels/ShareDrawer.tsx @@ -88,7 +88,9 @@ export function ShareDrawer({ setRemixes(doc0Remixes); } - getHistoryAndRemixes(); + if (!contentData.isFolder) { + getHistoryAndRemixes(); + } }, [contentData]); useEffect(() => { @@ -144,16 +146,20 @@ export function ShareDrawer({ Share - - Remixed From{" "} - {contributorHistory !== null - ? `(${contributorHistory.length})` - : null} - {haveChangedHistoryItem ? "*" : null} - - - Remixes {remixes !== null ? `(${remixes.length})` : null} - + {!contentData.isFolder ? ( + <> + + Remixed From{" "} + {contributorHistory !== null + ? `(${contributorHistory.length})` + : null} + {haveChangedHistoryItem ? "*" : null} + + + Remixes {remixes !== null ? `(${remixes.length})` : null} + + + ) : null} @@ -164,15 +170,19 @@ export function ShareDrawer({ allLicenses={allLicenses} /> - - - - - - + {!contentData.isFolder ? ( + <> + + + + + + + + ) : null} diff --git a/client/src/Tools/_framework/ToolPanels/ShareSettings.tsx b/client/src/Tools/_framework/ToolPanels/ShareSettings.tsx index 8939ead8a..597a32be1 100644 --- a/client/src/Tools/_framework/ToolPanels/ShareSettings.tsx +++ b/client/src/Tools/_framework/ToolPanels/ShareSettings.tsx @@ -259,6 +259,7 @@ export function ShareSettings({ {statusText !== "" ? ( setShareWithEmail(e.target.value)} width="90%" /> diff --git a/client/src/Widgets/ActivityTable.tsx b/client/src/Widgets/ActivityTable.tsx index 14af010e9..60e495da5 100644 --- a/client/src/Widgets/ActivityTable.tsx +++ b/client/src/Widgets/ActivityTable.tsx @@ -115,6 +115,7 @@ export default forwardRef(function ActivityTable( return ( diff --git a/client/src/Widgets/ContentCard.tsx b/client/src/Widgets/ContentCard.tsx index eeaca42db..dbac51a4a 100644 --- a/client/src/Widgets/ContentCard.tsx +++ b/client/src/Widgets/ContentCard.tsx @@ -155,6 +155,7 @@ export default forwardRef(function ContentCard( margin="0" height="1em" fontWeight="bold" + data-test="Editable Title" autoFocus={autoFocusTitle} onFocus={(e) => e.target.select()} onChange={(e) => setCardTitle(e.target.value)} From 3672944784dfbb5f8f35cdeb8fac64a6a2418f25 Mon Sep 17 00:00:00 2001 From: Duane Nykamp Date: Wed, 14 Aug 2024 08:23:55 -0500 Subject: [PATCH 3/9] check for notMe even when searching folder --- client/src/Tools/_framework/Paths/Activities.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/src/Tools/_framework/Paths/Activities.tsx b/client/src/Tools/_framework/Paths/Activities.tsx index c7ec1b106..bd7c454e2 100644 --- a/client/src/Tools/_framework/Paths/Activities.tsx +++ b/client/src/Tools/_framework/Paths/Activities.tsx @@ -159,12 +159,12 @@ export async function loader({ params, request }) { `/api/getMyFolderContent/${params.userId}/${params.folderId ?? ""}`, ); data = results.data; + } - if (data.notMe) { - return redirect( - `/sharedActivities/${params.userId}${params.folderId ? "/" + params.folderId : ""}`, - ); - } + if (data.notMe) { + return redirect( + `/sharedActivities/${params.userId}${params.folderId ? "/" + params.folderId : ""}`, + ); } let prefData = await axios.get(`/api/getPreferredFolderView`); From 8b275cf6a44b16277ca0ad6c9ee12fa0691bb859 Mon Sep 17 00:00:00 2001 From: Duane Nykamp Date: Wed, 14 Aug 2024 22:38:17 -0500 Subject: [PATCH 4/9] fix regressions for anonymous user login --- .../src/Tools/_framework/Paths/ChangeName.tsx | 49 +++++-------------- server/src/index.ts | 14 +++--- 2 files changed, 20 insertions(+), 43 deletions(-) diff --git a/client/src/Tools/_framework/Paths/ChangeName.tsx b/client/src/Tools/_framework/Paths/ChangeName.tsx index 17a859268..5235f0a8e 100644 --- a/client/src/Tools/_framework/Paths/ChangeName.tsx +++ b/client/src/Tools/_framework/Paths/ChangeName.tsx @@ -70,47 +70,24 @@ export function ChangeName({ const [statusText, setStatusText] = useState(""); useEffect(() => { - if (submitted && user !== undefined) { - setStatusText(`Name changed to ${createFullName(user)}`); - if ( - redirectTo && - user.firstNames === firstNames && - user.lastNames === lastNames - ) { - navigate(redirectTo); + if (submitted) { + if (user === undefined) { + setStatusText("Cannot change name; no user logged in."); } else { - setSubmitted(false); + setStatusText(`Name changed to ${createFullName(user)}`); + if ( + redirectTo && + user.firstNames === firstNames && + user.lastNames === lastNames + ) { + navigate(redirectTo); + } else { + setSubmitted(false); + } } } }, [user]); - if (!user) { - return ( - - - Cannot change name; no user logged in. - - - - ); - } - return ( Enter your name diff --git a/server/src/index.ts b/server/src/index.ts index 04dcf236f..7e640f763 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -271,14 +271,14 @@ passport.serializeUser(async (_req, user: any, done) => { ) { if (req.body.email) { email = req.body.email; + if (req.body.firstNames) { + firstNames = req.body.firstNames; + } + if (req.body.lastNames) { + lastNames = req.body.lastNames; + } + isAnonymous = false; } - if (req.body.firstNames) { - firstNames = req.body.firstNames; - } - if (req.body.lastNames) { - lastNames = req.body.lastNames; - } - isAnonymous = false; } const u = await findOrCreateUser({ From bfad20a4b57f7e08552580ef208dd47223f2cb8c Mon Sep 17 00:00:00 2001 From: Duane Nykamp Date: Wed, 14 Aug 2024 22:49:38 -0500 Subject: [PATCH 5/9] fix regression in share drawer --- .../_framework/ToolPanels/ShareDrawer.tsx | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/client/src/Tools/_framework/ToolPanels/ShareDrawer.tsx b/client/src/Tools/_framework/ToolPanels/ShareDrawer.tsx index 26091001b..8cc4d4dc9 100644 --- a/client/src/Tools/_framework/ToolPanels/ShareDrawer.tsx +++ b/client/src/Tools/_framework/ToolPanels/ShareDrawer.tsx @@ -171,17 +171,17 @@ export function ShareDrawer({ /> {!contentData.isFolder ? ( - <> - - - - - - - + + + + ) : null} + {!contentData.isFolder ? ( + + + ) : null} From 797ec9fe69ace0881e9adc557bd131beb7413739 Mon Sep 17 00:00:00 2001 From: Duane Nykamp Date: Thu, 15 Aug 2024 18:55:00 -0500 Subject: [PATCH 6/9] submit share on blur cannot share with self --- .../_framework/ToolPanels/ShareSettings.tsx | 33 +++++++++++--- server/src/index.ts | 18 +++++++- server/src/model.test.ts | 44 +++++++++++++++++++ server/src/model.ts | 8 ++-- 4 files changed, 92 insertions(+), 11 deletions(-) diff --git a/client/src/Tools/_framework/ToolPanels/ShareSettings.tsx b/client/src/Tools/_framework/ToolPanels/ShareSettings.tsx index 597a32be1..cdfb18c04 100644 --- a/client/src/Tools/_framework/ToolPanels/ShareSettings.tsx +++ b/client/src/Tools/_framework/ToolPanels/ShareSettings.tsx @@ -32,6 +32,7 @@ import { Show, VStack, Hide, + Button, } from "@chakra-ui/react"; import { ContentStructure, @@ -69,19 +70,22 @@ export async function sharingActions({ formObj }: { [k: string]: any }) { } return true; } else if (formObj._action === "share content") { + let noSelfShare = false; try { if (formObj.isFolder === "true") { - await axios.post("/api/shareFolder", { + const { data } = await axios.post("/api/shareFolder", { id: Number(formObj.id), licenseCode: formObj.licenseCode, email: formObj.email, }); + noSelfShare = Boolean(data.noSelfShare); } else { - await axios.post("/api/shareActivity", { + const { data } = await axios.post("/api/shareActivity", { id: Number(formObj.id), licenseCode: formObj.licenseCode, email: formObj.email, }); + noSelfShare = Boolean(data.noSelfShare); } } catch (e) { if (e.response?.data === "User with email not found") { @@ -90,7 +94,11 @@ export async function sharingActions({ formObj }: { [k: string]: any }) { throw e; } } - return { status: "Added", email: formObj.email }; + if (noSelfShare) { + return { status: "No self share" }; + } else { + return { status: "Added", email: formObj.email }; + } } else if (formObj._action === "unshare content") { if (formObj.isFolder === "true") { await axios.post("/api/unshareFolder", { @@ -150,6 +158,7 @@ export function ShareSettings({ const [errorMessage, setErrorMessage] = useState(""); const initialActionResult = useRef(true); + const shareSubmitButton = useRef(null); useEffect(() => { setSelectedLicenseCode(license?.code); @@ -172,14 +181,22 @@ export function ShareSettings({ if (actionResult?.status === "Added") { setShareWithEmail(""); setErrorMessage(""); - } else if (actionResult?.status === "Not found") { + } else if ( + actionResult?.status === "Not found" || + actionResult?.status === "No self share" + ) { nextStatusText.current = ""; setStatusText(""); setShowSpinner(null); // Need this check so don't get old error message when reopening the controls if (!initialActionResult.current) { - setErrorMessage(`User with email ${actionResult.email} not found`); + if (actionResult) + if (actionResult.status === "No self share") { + setErrorMessage("Cannot share with yourself"); + } else { + setErrorMessage(`User with email ${actionResult.email} not found`); + } } } else { setErrorMessage(""); @@ -454,6 +471,11 @@ export function ShareSettings({ data-test="Email address" onChange={(e) => setShareWithEmail(e.target.value)} width="90%" + onBlur={(e) => { + if (e.target.value) { + shareSubmitButton.current?.click(); + } + }} />