diff --git a/RELEASE.md b/RELEASE.md index 7d03f5c..ea9314c 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,5 +1,13 @@ # Changelog +## [1.3.1] - 2025-09-21 +- Improved width of links in tables +- Fixed asset page not showing domains +- Fixed domain assets shown under global assets +- Improve asset delete modal text +- Removed asset preview icon background +- Minor improvements to install / login UI. + ## [1.3.0] - 2025-09-19 - Added dark mode support and various UI improvements - Added manual backup functionality diff --git a/backend/repository/asset.go b/backend/repository/asset.go index 80d0a22..8326296 100644 --- a/backend/repository/asset.go +++ b/backend/repository/asset.go @@ -57,7 +57,7 @@ func (r *Asset) GetAllByDomainAndContext( db = db. Joins("left join domains on domains.id = assets.domain_id"). Select(r.joinSelectString()). - Where("(assets.company_id = ? OR assets.company_id IS NULL) AND (domain_id = ? OR domain_id IS NULL)", companyID, domainID) + Where("(assets.company_id = ? OR assets.company_id IS NULL) AND domain_id = ?", companyID, domainID) } else { db.Where("assets.company_id = ?", companyID) } @@ -103,7 +103,7 @@ func (r *Asset) GetAllByGlobalContext( } var dbModels []*database.Asset dbRes := db. - Where("company_id IS NULL"). + Where("company_id IS NULL AND domain_id IS NULL"). Find(&dbModels) if dbRes.Error != nil { diff --git a/backend/testfiles/attachment.txt b/backend/testfiles/assets/attachment-a.txt similarity index 100% rename from backend/testfiles/attachment.txt rename to backend/testfiles/assets/attachment-a.txt diff --git a/backend/testfiles/assets/attachment-b.txt b/backend/testfiles/assets/attachment-b.txt new file mode 100644 index 0000000..9562308 --- /dev/null +++ b/backend/testfiles/assets/attachment-b.txt @@ -0,0 +1 @@ +Hi {{.FirstName}} Welcome to The Phishing Club! We are excited to have you here. Click here to get started. diff --git a/backend/testfiles/assets/contoso-logo.png b/backend/testfiles/assets/contoso-logo.png new file mode 100644 index 0000000..781fd40 Binary files /dev/null and b/backend/testfiles/assets/contoso-logo.png differ diff --git a/backend/testfiles/assets/domain.tld/contoso-logo.png b/backend/testfiles/assets/domain.tld/contoso-logo.png new file mode 100644 index 0000000..b48bde5 Binary files /dev/null and b/backend/testfiles/assets/domain.tld/contoso-logo.png differ diff --git a/backend/testfiles/assets/domain.tld/style.css b/backend/testfiles/assets/domain.tld/style.css new file mode 100644 index 0000000..14600ec --- /dev/null +++ b/backend/testfiles/assets/domain.tld/style.css @@ -0,0 +1,5 @@ +/** domain asset **/ +* { + background-color: red; + background: url(contoso-logo.png); +} diff --git a/backend/testfiles/assets/style.css b/backend/testfiles/assets/style.css new file mode 100644 index 0000000..2ea8343 --- /dev/null +++ b/backend/testfiles/assets/style.css @@ -0,0 +1,5 @@ +/** global asset **/ +* { + background-color: yellow; + background: url(contoso-logo.png); +} diff --git a/backend/testfiles/test.key b/backend/testfiles/certs/test.key similarity index 100% rename from backend/testfiles/test.key rename to backend/testfiles/certs/test.key diff --git a/backend/testfiles/test.pem b/backend/testfiles/certs/test.pem similarity index 100% rename from backend/testfiles/test.pem rename to backend/testfiles/certs/test.pem diff --git a/backend/testfiles/license.json b/backend/testfiles/license.json deleted file mode 100644 index 846265c..0000000 --- a/backend/testfiles/license.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "version": "v1", - "company": "Phishing Club", - "key": "", - "validUntil": "2025-12-23T15:30:22.635975262Z", - "isValid": true, - "signature": "lr9fmt3LqacnLzmQ3TAg5P8lQJ0R9OwNjKGa1s6nLE0=", - "offlineActivated": true -} diff --git a/backend/testfiles/recipients-2.csv b/backend/testfiles/recipients/recipients-2.csv similarity index 100% rename from backend/testfiles/recipients-2.csv rename to backend/testfiles/recipients/recipients-2.csv diff --git a/backend/testfiles/recipients.csv b/backend/testfiles/recipients/recipients.csv similarity index 100% rename from backend/testfiles/recipients.csv rename to backend/testfiles/recipients/recipients.csv diff --git a/backend/testfiles/reporters.csv b/backend/testfiles/reporters/reporters.csv similarity index 100% rename from backend/testfiles/reporters.csv rename to backend/testfiles/reporters/reporters.csv diff --git a/frontend/src/lib/api/middleware.js b/frontend/src/lib/api/middleware.js index 185fb33..bd4fe7e 100644 --- a/frontend/src/lib/api/middleware.js +++ b/frontend/src/lib/api/middleware.js @@ -12,9 +12,9 @@ export const immediateResponseHandler = (apiResponse) => { goto('/login'); window.location.reload(); } - // If the user must renew their password, move them to the renew password page + // If the user must renew their password, redirect to login if (apiResponse.statusCode === 400 && apiResponse.error === 'New password required') { - goto('/login/reset-password'); + goto('/login'); return; } return apiResponse; diff --git a/frontend/src/lib/components/ThemeToggle.svelte b/frontend/src/lib/components/ThemeToggle.svelte index 9253c2a..06c2a5a 100644 --- a/frontend/src/lib/components/ThemeToggle.svelte +++ b/frontend/src/lib/components/ThemeToggle.svelte @@ -11,13 +11,13 @@ {:else} {:else} diff --git a/frontend/src/routes/asset/+page.svelte b/frontend/src/routes/asset/+page.svelte index 5c5a1d4..295afca 100644 --- a/frontend/src/routes/asset/+page.svelte +++ b/frontend/src/routes/asset/+page.svelte @@ -36,7 +36,7 @@ const refresh = async () => { try { isTableLoading = true; - const res = await api.domain.getAll(tableURLParams, contextCompanyID); + const res = await api.domain.getAllSubset(tableURLParams, contextCompanyID); if (!res.success) { throw res.error; } diff --git a/frontend/src/routes/asset/[domain]/+page.svelte b/frontend/src/routes/asset/[domain]/+page.svelte index 4b37730..7bb1dc1 100644 --- a/frontend/src/routes/asset/[domain]/+page.svelte +++ b/frontend/src/routes/asset/[domain]/+page.svelte @@ -54,7 +54,8 @@ let isDeleteAlertVisible = false; let deleteValues = { id: null, - name: null + name: null, + path: null }; let modalMode = null; let modalText = ''; @@ -251,6 +252,7 @@ isDeleteAlertVisible = true; deleteValues.id = asset.id; deleteValues.name = asset.name; + deleteValues.path = asset.path; }; const onClickPreview = async (path) => { @@ -396,7 +398,7 @@ {#if isImageFile(asset.path)} {#await getImagePreviewUrl(asset.path)} -
+
{:then imageUrl} {#if imageUrl} @@ -274,6 +275,7 @@ }} {...globalButtonDisabledAttributes(attachment, contextCompanyID)} title={attachment.name} + class="block w-full py-1 text-left" > {attachment.description} @@ -287,6 +289,7 @@ }} {...globalButtonDisabledAttributes(attachment, contextCompanyID)} title={attachment.name} + class="block w-full py-1 text-left" > {attachment.fileName} diff --git a/frontend/src/routes/campaign-template/+page.svelte b/frontend/src/routes/campaign-template/+page.svelte index bb26db1..038eb94 100644 --- a/frontend/src/routes/campaign-template/+page.svelte +++ b/frontend/src/routes/campaign-template/+page.svelte @@ -7,6 +7,7 @@ import TextField from '$lib/components/TextField.svelte'; import TableRow from '$lib/components/table/TableRow.svelte'; import TableCell from '$lib/components/table/TableCell.svelte'; + import TableCellLink from '$lib/components/table/TableCellLink.svelte'; import TableUpdateButton from '$lib/components/table/TableUpdateButton.svelte'; import TableDeleteButton from '$lib/components/table/TableDeleteButton2.svelte'; import TableCellAction from '$lib/components/table/TableCellAction.svelte'; @@ -473,62 +474,70 @@ on:click={() => openUpdateModal(template.id)} {...globalButtonDisabledAttributes(template, contextCompanyID)} title={template.name} + class="block w-full py-1 text-left" > {template.name}
{#if template.domainID} - + {domainMap.byKey(template.domainID)} {/if} {#if template.smtpConfigurationID} - + {smtpConfigurationMap.byKey(template.smtpConfigurationID)} {/if} {#if template.apiSenderID} - + {apiSenderMap.byKey(template.apiSenderID)} {/if} {#if template.emailID} - + {emailMap.byKey(template.emailID)} {/if} {#if template.beforeLandingPageID} - + {beforeLandingPageMap.byKey(template.beforeLandingPageID)} {/if} {#if template.landingPageID} - + {landingPageMap.byKey(template.landingPageID)} {/if} {#if template.afterLandingPageID} - + {afterLandingPageMap.byKey(template.afterLandingPageID)} {/if} {#if template.afterLandingPageRedirectURL} - + {template.afterLandingPageRedirectURL} {/if} diff --git a/frontend/src/routes/campaign/+page.svelte b/frontend/src/routes/campaign/+page.svelte index 7269813..002f216 100644 --- a/frontend/src/routes/campaign/+page.svelte +++ b/frontend/src/routes/campaign/+page.svelte @@ -8,6 +8,7 @@ import TextField from '$lib/components/TextField.svelte'; import TableRow from '$lib/components/table/TableRow.svelte'; import TableCell from '$lib/components/table/TableCell.svelte'; + import TableCellLink from '$lib/components/table/TableCellLink.svelte'; import TableUpdateButton from '$lib/components/table/TableUpdateButton.svelte'; import TableDeleteButton from '$lib/components/table/TableDeleteButton2.svelte'; import { addToast } from '$lib/store/toast'; @@ -994,22 +995,21 @@ > {#each campaigns as campaign} - + {#if campaign.isTest} {/if} - - {campaign.name} - - + {campaign.name} + {toEvent(campaign.notableEventName).name} - - - {templateMap.byKey(campaign.templateID)} - - + + {templateMap.byKey(campaign.templateID)} + diff --git a/frontend/src/routes/campaign/[id]/+page.svelte b/frontend/src/routes/campaign/[id]/+page.svelte index 622020a..e89246a 100644 --- a/frontend/src/routes/campaign/[id]/+page.svelte +++ b/frontend/src/routes/campaign/[id]/+page.svelte @@ -10,6 +10,7 @@ import { AppStateService } from '$lib/service/appState'; import TableRow from '$lib/components/table/TableRow.svelte'; import TableCell from '$lib/components/table/TableCell.svelte'; + import TableCellLink from '$lib/components/table/TableCellLink.svelte'; import { formatWeekDays, formatTimeConstraint, timeFormat } from '$lib/utils/date.js'; import { defaultPerPage, @@ -1362,21 +1363,21 @@ {#if event.recipient?.firstName} - + {event.recipient.firstName} {/if} {#if event.recipient?.lastName} - + {event.recipient.lastName} {/if} {#if event.recipient?.email} - + {event.recipient.email} {/if} @@ -1430,18 +1431,27 @@ {:else} - - {#if recp?.recipient?.email} - {/if} diff --git a/frontend/src/routes/company/+page.svelte b/frontend/src/routes/company/+page.svelte index f07f290..bfe84f4 100644 --- a/frontend/src/routes/company/+page.svelte +++ b/frontend/src/routes/company/+page.svelte @@ -246,6 +246,7 @@ on:click={() => { openUpdateModal(company.id); }} + class="block w-full py-1 text-left" > {company.name} diff --git a/frontend/src/routes/domain/+page.svelte b/frontend/src/routes/domain/+page.svelte index 0aa7ec6..7303107 100644 --- a/frontend/src/routes/domain/+page.svelte +++ b/frontend/src/routes/domain/+page.svelte @@ -10,6 +10,7 @@ import CheckboxField from '$lib/components/CheckboxField.svelte'; import TableRow from '$lib/components/table/TableRow.svelte'; import TableCell from '$lib/components/table/TableCell.svelte'; + import TableCellLink from '$lib/components/table/TableCellLink.svelte'; import TableUpdateButton from '$lib/components/table/TableUpdateButton.svelte'; import TableDeleteButton from '$lib/components/table/TableDeleteButton2.svelte'; import { addToast } from '$lib/store/toast'; @@ -538,6 +539,7 @@ }} {...globalButtonDisabledAttributes(domain, contextCompanyID)} title={domain.name} + class="block w-full py-1 text-left" > {domain.name} diff --git a/frontend/src/routes/email/+page.svelte b/frontend/src/routes/email/+page.svelte index 46fb32c..21480e1 100644 --- a/frontend/src/routes/email/+page.svelte +++ b/frontend/src/routes/email/+page.svelte @@ -8,6 +8,7 @@ import Headline from '$lib/components/Headline.svelte'; import TextField from '$lib/components/TextField.svelte'; import TableCell from '$lib/components/table/TableCell.svelte'; + import TableCellLink from '$lib/components/table/TableCellLink.svelte'; import TableRow from '$lib/components/table/TableRow.svelte'; import TableUpdateButton from '$lib/components/table/TableUpdateButton.svelte'; import TableDeleteButton from '$lib/components/table/TableDeleteButton2.svelte'; @@ -394,6 +395,7 @@ }} {...globalButtonDisabledAttributes(email, contextCompanyID)} title={email.name} + class="block w-full py-1 text-left" > {email.name} diff --git a/frontend/src/routes/install/+page.svelte b/frontend/src/routes/install/+page.svelte index 662480b..bcb926c 100644 --- a/frontend/src/routes/install/+page.svelte +++ b/frontend/src/routes/install/+page.svelte @@ -1,4 +1,5 @@ - - -
-
- Current password has expired. Set a new password - Current password - New password - Repeat new password - - Change Password - -
diff --git a/frontend/src/routes/page/+page.svelte b/frontend/src/routes/page/+page.svelte index 6aa27f9..2da9d27 100644 --- a/frontend/src/routes/page/+page.svelte +++ b/frontend/src/routes/page/+page.svelte @@ -8,6 +8,7 @@ import TextField from '$lib/components/TextField.svelte'; import TableRow from '$lib/components/table/TableRow.svelte'; import TableCell from '$lib/components/table/TableCell.svelte'; + import TableCellLink from '$lib/components/table/TableCellLink.svelte'; import TableUpdateButton from '$lib/components/table/TableUpdateButton.svelte'; import TableDeleteButton from '$lib/components/table/TableDeleteButton2.svelte'; import FormError from '$lib/components/FormError.svelte'; @@ -315,6 +316,7 @@ }} {...globalButtonDisabledAttributes(page, contextCompanyID)} title={page.name} + class="block w-full py-1 text-left" > {page.name} diff --git a/frontend/src/routes/recipient/+page.svelte b/frontend/src/routes/recipient/+page.svelte index 7817da4..9bb7c14 100644 --- a/frontend/src/routes/recipient/+page.svelte +++ b/frontend/src/routes/recipient/+page.svelte @@ -7,6 +7,7 @@ import TextField from '$lib/components/TextField.svelte'; import TableRow from '$lib/components/table/TableRow.svelte'; import TableCell from '$lib/components/table/TableCell.svelte'; + import TableCellLink from '$lib/components/table/TableCellLink.svelte'; import TableUpdateButton from '$lib/components/table/TableUpdateButton.svelte'; import TableDeleteButton from '$lib/components/table/TableDeleteButton2.svelte'; import { addToast } from '$lib/store/toast'; @@ -406,19 +407,18 @@ > {#each recipients as recipient} - + {#if recipient.email} - - {recipient.email} - + {recipient.email} {/if} - + {#if recipient.firstName} @@ -430,6 +430,7 @@ on:click={() => { openUpdateModal(recipient.id); }} + class="block w-full py-1 text-left" > {recipient.lastName} diff --git a/frontend/src/routes/recipient/group/+page.svelte b/frontend/src/routes/recipient/group/+page.svelte index 972b31d..50c63fe 100644 --- a/frontend/src/routes/recipient/group/+page.svelte +++ b/frontend/src/routes/recipient/group/+page.svelte @@ -8,6 +8,7 @@ import TextField from '$lib/components/TextField.svelte'; import TableRow from '$lib/components/table/TableRow.svelte'; import TableCell from '$lib/components/table/TableCell.svelte'; + import TableCellLink from '$lib/components/table/TableCellLink.svelte'; import TableUpdateButton from '$lib/components/table/TableUpdateButton.svelte'; import TableDeleteButton from '$lib/components/table/TableDeleteButton2.svelte'; import { addToast } from '$lib/store/toast'; @@ -232,17 +233,13 @@ > {#each groups as group} - - - {group.name} - - + + {group.name} + - - - {group.recipientCount} - - + + {group.recipientCount} + diff --git a/frontend/src/routes/recipient/group/[id]/+page.svelte b/frontend/src/routes/recipient/group/[id]/+page.svelte index 87406eb..e2fb6c3 100644 --- a/frontend/src/routes/recipient/group/[id]/+page.svelte +++ b/frontend/src/routes/recipient/group/[id]/+page.svelte @@ -9,6 +9,7 @@ import SubHeadline from '$lib/components/SubHeadline.svelte'; import TableRow from '$lib/components/table/TableRow.svelte'; import TableCell from '$lib/components/table/TableCell.svelte'; + import TableCellLink from '$lib/components/table/TableCellLink.svelte'; import { addToast } from '$lib/store/toast'; import FormError from '$lib/components/FormError.svelte'; import TableCellEmpty from '$lib/components/table/TableCellEmpty.svelte'; @@ -391,16 +392,16 @@ {#each recipients as recipient} - - {recipient.firstName} - - - {recipient.lastName} - + + {recipient.firstName} + + + {recipient.lastName} + - - {recipient.extraIdentifier} - + + {recipient.extraIdentifier} + diff --git a/frontend/src/routes/smtp-configuration/+page.svelte b/frontend/src/routes/smtp-configuration/+page.svelte index ac63dcd..409fe56 100644 --- a/frontend/src/routes/smtp-configuration/+page.svelte +++ b/frontend/src/routes/smtp-configuration/+page.svelte @@ -441,6 +441,7 @@ }} {...globalButtonDisabledAttributes(conf, contextCompanyID)} title={conf.name} + class="block w-full py-1 text-left" > {conf.name} diff --git a/frontend/src/routes/user/+page.svelte b/frontend/src/routes/user/+page.svelte index 8a1b6ff..ecf29c3 100644 --- a/frontend/src/routes/user/+page.svelte +++ b/frontend/src/routes/user/+page.svelte @@ -263,6 +263,7 @@ on:click={() => { showEditModal(user.id); }} + class="block w-full py-1 text-left" > {user.username}