Skip to content
Closed
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
1 change: 1 addition & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Binary file removed .yarn/cache/fsevents-patch-19706e7e35-10.zip
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { TimerInterface } from '@standardnotes/time'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { StatisticMeasureName } from '../Statistics/StatisticMeasureName'
import { Period } from '../Time/Period'
import { safeHtml } from '@standardnotes/common'

const countActiveUsers = (measureName: string, data: any): { yesterday: number; last30Days: number } => {
const totalActiveUsersLast30DaysIncludingToday = data.statisticsOverTime.find(
Expand Down Expand Up @@ -567,7 +568,7 @@ export const html = (data: any, timer: TimerInterface) => {
const totalActivePlusUsers = countActiveUsers(StatisticMeasureName.NAMES.ActivePlusUsers, data)
const totalActiveProUsers = countActiveUsers(StatisticMeasureName.NAMES.ActiveProUsers, data)

return ` <div>
return safeHtml` <div>
<p>Hello,</p>
<p>
<strong>Here are some statistics from yesterday:</strong>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const html = (userEmail: string, offlineSubscriptionDashboardUrl: string) => `<div class="sn-component">
import { safeHtml } from '@standardnotes/common'

export const html = (userEmail: string, offlineSubscriptionDashboardUrl: string) => safeHtml`<div class="sn-component">
<div class="sk-panel static">
<div class="sk-panel-content">
<div class="sk-panel-section">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const html = (inviterIdentifier: string, inviteUuid: string) => `<p>Hello,</p>
import { safeHtml } from '@standardnotes/common'

export const html = (inviterIdentifier: string, inviteUuid: string) => safeHtml`<p>Hello,</p>
<p>You've been invited to join a Standard Notes premium subscription at no cost. ${inviterIdentifier} has invited you to share the benefits of their subscription plan.</p>
<p>
<a href='https://app.standardnotes.com/?accept-subscription-invite=${inviteUuid}'>Accept Invite</a>
Expand Down
4 changes: 3 additions & 1 deletion packages/auth/src/Domain/Email/user-email-changed.html.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const html = (newEmail: string) => `
import { safeHtml } from '@standardnotes/common'

export const html = (newEmail: string) => safeHtml`
<p>Hello,</p>

<p>We are writing to inform you that your request to update your email address has been successfully processed. The email address associated with your Standard Notes account has now been changed to the following:</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const html = () => `
import { safeHtml } from '@standardnotes/common'

export const html = () => safeHtml`
<p>Hello,</p>

<p>You've been invited to join a shared vault. This shared workspace will help you collaborate and securely manage notes and files.</p>
Expand Down
4 changes: 3 additions & 1 deletion packages/auth/src/Domain/Email/user-signed-in.html.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const html = (email: string, device: string, browser: string, timeAndDate: string) => `
import { safeHtml } from '@standardnotes/common'

export const html = (email: string, device: string, browser: string, timeAndDate: string) => safeHtml`
<div>
<p>Hello,</p>
<p>We've detected a new sign-in to your account ${email}</p>
Expand Down
16 changes: 16 additions & 0 deletions packages/common/src/Domain/Html/SafeHtml.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { safeHtml } from './SafeHtml'

describe('html', () => {
test('Should escape html from user input', () => {
const basicStringInput = '<h1>User</h1>'
const numberValue = 10
expect(safeHtml`<p>Hello world, ${basicStringInput} ${numberValue}</p>`).toBe(
'<p>Hello world, &lt;h1&gt;User&lt;/h1&gt; 10</p>',
)
})

test('Should join arrays and escape', () => {
const arrayOfStrings = ['<h1>User</h1>', '<p>Test</p>']
expect(safeHtml`<p>${arrayOfStrings}</p>`).toBe('<p>&lt;h1&gt;User&lt;/h1&gt;&lt;p&gt;Test&lt;/p&gt;</p>')
})
})
32 changes: 32 additions & 0 deletions packages/common/src/Domain/Html/SafeHtml.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
function escapeHTML(str: string) {
return str
.replace(/&/g, '&amp;')
.replace(/>/g, '&gt;')
.replace(/</g, '&lt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
.replace(/`/g, '&#96;')
}

/**
* Template handler that does basic HTML escaping for substitutions
*/
export function safeHtml(literals: TemplateStringsArray, ...substitutions: Array<string | number | string[]>) {
const raw = literals.raw

let result = raw[0]

for (let index = 1; index < raw.length; index++) {
const literal = raw[index]
let substitution = substitutions[index - 1]
if (Array.isArray(substitution)) {
substitution = substitution.join('')
} else if (typeof substitution === 'number') {
substitution = substitution.toString()
}
substitution = escapeHTML(substitution)
result += substitution + literal
}

return result
}
1 change: 1 addition & 0 deletions packages/common/src/Domain/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ export * from './Subscription/SubscriptionName'
export * from './Type/Either'
export * from './Type/Only'
export * from './User/UserRequestType'
export * from './Html/SafeHtml'
1 change: 1 addition & 0 deletions packages/scheduler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"dependencies": {
"@aws-sdk/client-sns": "^3.484.0",
"@aws-sdk/client-sqs": "^3.484.0",
"@standardnotes/common": "workspace:^",
"@standardnotes/domain-core": "workspace:^",
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const html = `<div>
import { safeHtml } from '@standardnotes/common'

export const html = safeHtml`<div>
<p>
Did you know you can enable daily email backups for your account? This <strong>free</strong> feature sends an
email to your inbox with an encrypted backup file including all your notes and tags.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const html = (registrationDate: string, annualPlusPrice: number, annualProPrice: number) => `<div>
import { safeHtml } from '@standardnotes/common'

export const html = (registrationDate: string, annualPlusPrice: number, annualProPrice: number) => safeHtml`<div>
<p>Hi there,</p>
<p>
We hope you've been finding great use out of Standard Notes. We built Standard Notes to be a secure place for
Expand Down
4 changes: 3 additions & 1 deletion packages/scheduler/src/Domain/Email/exit-interview.html.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const html = `<div>
import { safeHtml } from '@standardnotes/common'

export const html = safeHtml`<div>
<p>
We're truly sad to see you leave. Our mission is simple: build the best, most private, and most secure
note-taking app available. It's clear we've fallen short of your expectations somewhere along the way.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const html = `<p>Hello,</p>
import { safeHtml } from '@standardnotes/common'

export const html = safeHtml`<p>Hello,</p>
<p>We recently tried backing up your data to <strong>Dropbox</strong>, but an issue prevented us from doing so.</p>
<p>
The usual cause is an expired or revoked token from your sync provider. Please follow
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const html = (email: string) => `
import { safeHtml } from '@standardnotes/common'

export const html = (email: string) => safeHtml`
<p>
Your encrypted data backup is attached for ${email}. You can import this file using
the Standard Notes web or desktop app, or by using the offline decryption script available at
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const html = `<p>Hello,</p>
import { safeHtml } from '@standardnotes/common'

export const html = safeHtml`<p>Hello,</p>
<p>We recently tried backing up your data to <strong>Google Drive Sync</strong>, but an issue prevented us from
doing
so.</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const html = `<p>Hello,</p>
import { safeHtml } from '@standardnotes/common'

export const html = safeHtml`<p>Hello,</p>
<p>We recently tried backing up your data to <strong>OneDrive Sync</strong>, but an issue prevented us from doing
so.</p>
<p>
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6164,6 +6164,7 @@ __metadata:
dependencies:
"@aws-sdk/client-sns": "npm:^3.484.0"
"@aws-sdk/client-sqs": "npm:^3.484.0"
"@standardnotes/common": "workspace:^"
"@standardnotes/domain-core": "workspace:^"
"@standardnotes/domain-events": "workspace:*"
"@standardnotes/domain-events-infra": "workspace:*"
Expand Down
Loading