Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,10 @@ updates:
interval: "weekly"
cooldown:
default-days: 7

- package-ecosystem: "npm"
directory: "/src/Exceptionless.EmailTemplates"
schedule:
interval: "weekly"
cooldown:
default-days: 7
43 changes: 43 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,49 @@ jobs:
- name: Run Integration Tests
run: echo "npm run test:integration"

test-email-templates:
runs-on: ubuntu-latest
timeout-minutes: 15
defaults:
run:
working-directory: src/Exceptionless.EmailTemplates

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Setup Node.js environment
uses: actions/setup-node@v6
with:
node-version: 24

- name: Cache node_modules
uses: actions/cache@v5
id: cache-email-template-node-modules
with:
path: src/Exceptionless.EmailTemplates/node_modules
key: node-modules-email-${{ hashFiles('src/Exceptionless.EmailTemplates/package-lock.json') }}

- name: Install Npm Packages
if: steps.cache-email-template-node-modules.outputs.cache-hit != 'true'
run: npm ci

- name: Lint
run: npm run lint

- name: Type Check
run: npm run check

- name: Build Templates
run: npm run build

- name: Verify Generated HTML is Up-To-Date
run: |
if ! git diff --exit-code ../Exceptionless.Core/Mail/Templates/; then
echo "::error::Generated HTML templates are stale. Run 'npm run build' in src/Exceptionless.EmailTemplates and commit the updated files."
exit 1
fi

docker-build:
runs-on: ubuntu-latest
needs: [version]
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,4 @@ debug-storybook.log
.devcontainer/devcontainer-lock.json

*.lscache
.gstack/
137 changes: 137 additions & 0 deletions .gstack/browse-audit.jsonl

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions src/Exceptionless.AppHost/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,26 @@
})
.WithParentRelationship(api);
#pragma warning restore ASPIREBROWSERLOGS001

builder.AddJavaScriptApp("Storybook", "../Exceptionless.Web/ClientApp", "storybook")
.WithHttpEndpoint(port: 6006, targetPort: 6006, name: "http", isProxied: false)
.WithUrlForEndpoint("http", u =>
{
u.DisplayText = "Component Library";
u.DisplayOrder = 200;
})
.WithHttpHealthCheck("/")
.WithParentRelationship(api);

builder.AddJavaScriptApp("EmailStorybook", "../Exceptionless.EmailTemplates", "storybook")
.WithHttpEndpoint(port: 6008, targetPort: 6008, name: "http", isProxied: false)
.WithUrlForEndpoint("http", u =>
{
u.DisplayText = "Email Templates";
u.DisplayOrder = 300;
})
.WithHttpHealthCheck("/")
.WithParentRelationship(api);
}

await builder.Build().RunAsync();
3 changes: 2 additions & 1 deletion src/Exceptionless.Core/Mail/Mailer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ private static IEnumerable<object> GetStackTemplateData(IEnumerable<Stack> stack
StackId = s.Id,
Title = s.Title.Truncate(50),
TypeName = s.GetTypeName()?.Truncate(50),
s.Status
s.Status,
IsRegressed = s.Status == StackStatus.Regressed
});
}

Expand Down
6 changes: 4 additions & 2 deletions src/Exceptionless.Core/Mail/Templates/event-notice.html

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions src/Exceptionless.Core/Mail/Templates/organization-added.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

12 changes: 7 additions & 5 deletions src/Exceptionless.Core/Mail/Templates/project-daily-summary.html

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions src/Exceptionless.Core/Mail/Templates/user-email-verify.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" style="background:#f7f7f7!important"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width"><title>{{Subject}}</title><style>@media only screen{html{min-height:100%;background:#f7f7f7}}@media only screen and (max-width:596px){table.body img{width:auto;height:auto}table.body center{min-width:0!important}table.body .container{width:95%!important}table.body .columns{height:auto!important;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding-left:16px!important;padding-right:16px!important}th.small-3{display:inline-block!important;width:25%!important}th.small-4{display:inline-block!important;width:33.33333%!important}th.small-12{display:inline-block!important;width:100%!important}table.menu{width:100%!important}table.menu td,table.menu th{width:auto!important;display:inline-block!important}table.menu.vertical td,table.menu.vertical th{display:block!important}table.menu[align=center]{width:auto!important}}</style></head><body style="-moz-box-sizing:border-box;-ms-text-size-adjust:100%;-webkit-box-sizing:border-box;-webkit-text-size-adjust:100%;Margin:0;background:#f7f7f7!important;box-sizing:border-box;color:#2c2c2c;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;min-width:100%;padding:0;text-align:left;width:100%!important"><span class="preheader" style="color:#f7f7f7;display:none!important;font-size:1px;line-height:1px;max-height:0;max-width:0;mso-hide:all!important;opacity:0;overflow:hidden;visibility:hidden"></span><table class="body" style="Margin:0;background:#f7f7f7!important;border-collapse:collapse;border-spacing:0;color:#2c2c2c;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;height:100%;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;width:100%"><tr style="padding:0;text-align:left;vertical-align:top"><td class="center" align="center" valign="top" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#2c2c2c;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word"><center data-parsed style="min-width:580px;width:100%"><table align="center" class="wrapper header float-center" style="Margin:0 auto;background:#2c2c2c;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%"><tr style="padding:0;text-align:left;vertical-align:top"><td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#2c2c2c;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:8px 15px;text-align:left;vertical-align:top;word-wrap:break-word"><table align="center" class="container" style="Margin:0 auto;background:0 0;border-collapse:collapse;border-spacing:0;margin:0 auto;padding:0;text-align:inherit;vertical-align:top;width:580px"><tbody><tr style="padding:0;text-align:left;vertical-align:top"><td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#2c2c2c;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word"><img src="https://be.exceptionless.io/img/exceptionless-logo.png" alt="Exceptionless" style="-ms-interpolation-mode:bicubic;clear:both;display:block;margin-left:15px;max-width:100%;outline:0;text-decoration:none;width:auto"></td></tr></tbody></table></td></tr></table><table align="center" class="container float-center" style="Margin:0 auto;background:#f7f7f7;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:580px"><tbody><tr style="padding:0;text-align:left;vertical-align:top"><td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#2c2c2c;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word"><table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%"><tbody><tr style="padding:0;text-align:left;vertical-align:top"><td height="5px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#2c2c2c;font-family:Helvetica,Arial,sans-serif;font-size:5px;font-weight:400;hyphens:auto;line-height:5px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td></tr></tbody></table><table class="row" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%"><tbody><tr style="padding:0;text-align:left;vertical-align:top"><th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#2c2c2c;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0 auto;padding:0;padding-bottom:16px;padding-left:16px;padding-right:16px;text-align:left;width:564px"><table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%"><tr style="padding:0;text-align:left;vertical-align:top"><th style="Margin:0;color:#2c2c2c;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left"><h1 style="Margin:0;Margin-bottom:10px;color:inherit;font-family:Helvetica,Arial,sans-serif;font-size:34px;font-weight:400;line-height:1.3;margin:0;margin-bottom:5px;margin-top:0;padding:0;text-align:left;word-wrap:normal">Hello {{UserFullName}},</h1><p class="lead" style="Margin:0;Margin-bottom:10px;color:#2c2c2c;font-family:Helvetica,Arial,sans-serif;font-size:20px;font-weight:400;line-height:1.6;margin:0;margin-bottom:10px;padding:0;text-align:left">We're ready to activate your account. All we need to do is make sure this is your email address.</p><center data-parsed style="min-width:532px;width:100%"><table class="button button radius float-center" style="Margin:0 0 16px 0;border-collapse:collapse;border-spacing:0;float:none;margin:0 0 16px 0;padding:0;text-align:center;vertical-align:top;width:auto"><tr style="padding:0;text-align:left;vertical-align:top"><td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#2c2c2c;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word"><table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%"><tr style="padding:0;text-align:left;vertical-align:top"><td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;background:#5E9A00;border:none;border-collapse:collapse!important;border-radius:3px;color:#fefefe;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word"><a href="{{BaseUrl}}/account/verify?token={{UserVerifyEmailAddressToken}}" style="Margin:0;border:0 solid #5E9A00;border-radius:3px;color:#fefefe;display:inline-block;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:700;line-height:1.3;margin:0;padding:8px 16px 8px 16px;text-align:left;text-decoration:none">Verify Address </a></td></tr></table></td></tr></table></center><table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%"><tbody><tr style="padding:0;text-align:left;vertical-align:top"><td height="5px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#2c2c2c;font-family:Helvetica,Arial,sans-serif;font-size:5px;font-weight:400;hyphens:auto;line-height:5px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td></tr></tbody></table><p style="Margin:0;Margin-bottom:10px;color:#2c2c2c;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;text-align:left">If you didn't create an Exceptionless account, just delete this email and everything will go back to the way it was.</p></th><th class="expander" style="Margin:0;color:#2c2c2c;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th></tr></table></th></tr></tbody></table></td></tr></tbody></table><script type="application/ld+json" align="center" class="float-center">{
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html id="__better-svelte-email" lang="en" dir="ltr"><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="x-apple-disable-message-reformatting"><meta http-equiv="x-ua-compatible" content="IE=edge"></head><body><table align="center" width="100%" border="0" cellspacing="0" cellpadding="0" role="presentation"><tbody><tr><td style="background-color:rgb(247, 247, 247);font-family:Helvetica,Arial,sans-serif"><table align="center" width="100%" border="0" cellspacing="0" cellpadding="0" role="presentation" style="background-color:rgb(44, 44, 44);width:100%;padding-top:8px;padding-bottom:8px;padding-left:16px;padding-right:16px"><tbody><tr><td><table align="center" width="100%" role="presentation" cellspacing="0" cellpadding="0" border="0" style="max-width:37.5em;max-width:580px;margin-left:auto;margin-right:auto"><tbody><tr style="width: 100%;"><td><img alt="Exceptionless" src="https://be.exceptionless.io/img/exceptionless-logo.png" width="266" height="50" style="display:block;outline:none;border:none;text-decoration:none;display:block;margin-left:16px"></td></tr></tbody></table></td></tr></tbody></table><table align="center" width="100%" role="presentation" cellspacing="0" cellpadding="0" border="0" style="max-width:37.5em;max-width:580px;margin-left:auto;margin-right:auto;background-color:rgb(247, 247, 247)"><tbody><tr style="width: 100%;"><td><table align="center" width="100%" border="0" cellspacing="0" cellpadding="0" role="presentation" style="padding-top:8px;padding-bottom:8px;padding-left:16px;padding-right:16px"><tbody><tr><td><h1 style="font-size:34px;font-weight:400;color:rgb(44, 44, 44);line-height:1.3;margin-top:0px;margin-bottom:5px">Hello {{UserFullName}},</h1><p style="font-size:14px;line-height:24px;margin:16px 0;font-size:20px;line-height:1.6;color:rgb(44, 44, 44)">We're ready to activate your account. All we need to do is make sure this is your email address.</p><table align="center" width="100%" border="0" cellspacing="0" cellpadding="0" role="presentation" style="text-align:center"><tbody><tr><td><a href="{{BaseUrl}}/account/verify?token={{UserVerifyEmailAddressToken}}" target="_blank" style="line-height:100%;text-decoration:none;display:inline-block;max-width:100%;background-color:rgb(94, 154, 0);color:rgb(254, 254, 254);font-weight:700;font-size:16px;line-height:1.5;border-radius:3px;padding-left:16px;padding-right:16px;padding-top:8px;padding-bottom:8px;text-decoration-line:none;display:inline-block"><span></span><span style="max-width:100%;display:inline-block;line-height:120%;text-decoration:none;text-transform:none;mso-padding-alt:0px">Verify Address</span><span style="display: none;"></span></a></td></tr></tbody></table><p style="font-size:14px;line-height:24px;margin:16px 0;font-size:16px;line-height:1.5;color:rgb(44, 44, 44);line-height:1.3">If you didn't create an Exceptionless account, just delete this email and everything will go back to the way it was.</p></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table> <script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"description": "{{Subject}}",
Expand All @@ -14,4 +15,5 @@
"url": "https://exceptionless.com",
"logo": "https://be.exceptionless.io/img/exceptionless-48.png"
}
}</script></center></td></tr></table><!-- prevent Gmail on iOS font size manipulation --><div style="display:none;white-space:nowrap;font:15px courier;line-height:0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div></body></html>
}
</script></body></html>
Loading