Skip to content
Merged
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
34 changes: 27 additions & 7 deletions src/lib/components/wave/log-in-button/log-in-button.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import Button from '$lib/components/button/button.svelte';
import Github from '$lib/components/icons/Github.svelte';
import getOptionalEnvVar from '$lib/utils/get-optional-env-var/public';
import { PRIVACY_POLICY_VERSION, WAVE_TERMS_VERSION } from '$lib/utils/wave/legal-versions';

let {
backTo = page.url.pathname + page.url.search,
Expand Down Expand Up @@ -30,13 +31,32 @@
* campaigns / communities etc.
*/
let attributionRefParam = page.url.searchParams.get('ref');

/**
* Build the GitHub OAuth login URL with all the query params the wave
* backend round-trips through the OAuth `state` cookie. `termsVersion` and
* `privacyVersion` are required by the backend — they pin the consent
* record we write at login time to the exact document versions the user
* saw on screen.
*/
function buildLoginHref(): string {
const parts: string[] = [
`termsVersion=${encodeURIComponent(WAVE_TERMS_VERSION)}`,
`privacyVersion=${encodeURIComponent(PRIVACY_POLICY_VERSION)}`,
];

if (backTo) {
parts.push(`backTo=${encodeURIComponent(backTo)}`, `skipWelcome=${skipWelcome}`);
}

if (attributionRefParam) {
parts.push(`ref=${encodeURIComponent(attributionRefParam)}`);
}

return `${WAVE_API_URL}/api/auth/oauth/github/login?${parts.join('&')}`;
}
</script>

<Button
icon={Github}
{disabled}
variant={primary ? 'primary' : undefined}
href="{WAVE_API_URL}/api/auth/oauth/github/login{backTo
? `?backTo=${encodeURIComponent(backTo)}&skipWelcome=${skipWelcome}${attributionRefParam ? `&ref=${encodeURIComponent(attributionRefParam)}` : ''}`
: ''}">{wordy ? 'Log in with GitHub' : 'Log in'}</Button
<Button icon={Github} {disabled} variant={primary ? 'primary' : undefined} href={buildLoginHref()}
>{wordy ? 'Log in with GitHub' : 'Log in'}</Button
>
27 changes: 27 additions & 0 deletions src/lib/utils/wave/legal-versions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Versions of the legal documents the user implicitly consents to when
* completing the Wave login flow. These are reported to the wave backend on
* every login so the consent record is tied to exactly the document version
* the user saw on screen.
*
* Bump these values whenever the Terms & Rules or Privacy Policy is materially
* updated. The backend treats `(userId, termsVersion, privacyVersion)` as a
* unique tuple — bumping a version produces a fresh consent row on the next
* login while preserving the timestamp of any earlier consent.
*
* To keep "what was displayed" and "what was recorded" in lockstep, the
* privacy policy page imports `PRIVACY_POLICY_VERSION` for its effective-
* date line — so updating the doc text and bumping the constant happen in
* the same diff. The Wave Terms & Rules document lives off-repo at
* docs.drips.network, so `WAVE_TERMS_VERSION` is maintained by hand: bump
* it (and any displayed copy in the login flow) whenever the external doc
* is materially updated.
*
* Date-stamp format (YYYY-MM-DD) matches the date the version went live.
*/

/** Wave Terms & Rules: https://docs.drips.network/wave/terms-and-rules */
export const WAVE_TERMS_VERSION = '2026-04-27';

/** Drips Privacy Policy: /legal/privacy */
export const PRIVACY_POLICY_VERSION = '2026-04-29';
12 changes: 11 additions & 1 deletion src/routes/(pages)/(lp)/legal/privacy/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
<script>
import HeadMeta from '$lib/components/head-meta/head-meta.svelte';
import { PRIVACY_POLICY_VERSION } from '$lib/utils/wave/legal-versions';

// Format the YYYY-MM-DD constant as a human-readable date in the
// effective-date line below. Co-locating the display string with the
// constant guarantees that what the user sees and what we record on
// login consent come from the same source.
const effectiveDate = new Date(`${PRIVACY_POLICY_VERSION}T00:00:00Z`).toLocaleDateString(
'en-US',
{ year: 'numeric', month: 'long', day: 'numeric', timeZone: 'UTC' },
);
</script>

<HeadMeta title="Data & Privacy Policy" />
Expand Down Expand Up @@ -931,7 +941,7 @@

<section>
<h2>Validity and amendment of this privacy policy</h2>
<p>This privacy policy is currently valid and effective as of April 29, 2026.</p>
<p>This privacy policy is currently valid and effective as of {effectiveDate}.</p>
<p>
Due to the further development of the Drips Services or due to changes in legal or regulatory
requirements, it may become necessary to amend this privacy policy. In this case, we will
Expand Down
Loading