* Implement `Auth.TOTP.force_disable/1`
* Add "Reset 2FA" action to users CRM
* Add `Purge.reset!/2` variant allowing to set arbitrary cutoff time
* Add ability to set native stats start time from CRM
* Revert "Add `Purge.reset!/2` variant allowing to set arbitrary cutoff time"
This reverts commit 6f294d5d58.
* Add test for CRM site update action
* Reapply "Local CSV exports/imports and S3/UI updates (#3989)" (#3995)
This reverts commit aee69e44c8.
* remove unused functions
* eh, that one was actually used
* ugh, they were both used
---------
Co-authored-by: ruslandoga <67764432+ruslandoga@users.noreply.github.com>
* local CSV exports/imports and S3 updates
* credo
* dialyzer
* refactor input columns
* fix ci minio/clickhouse tests
* Update lib/plausible_web/live/csv_export.ex
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* fix date range filter in export_pages_q and process only pageviews
* remove toTimeZone(zero_timestamp) note
* use SiteImport.pending(), SiteImport.importing()
* escape [SiteImport.pending(), SiteImport.importing()]
* use random s3 keys for imports to avoid collisions (sometimes makes the upload get stuck)
* clamp import date ranges
* site is already in assigns
* recompute cutoff date each time
* use toDate(timestamp[, timezone]) shortcut
* show alreats on export cancel/delete and extract hint into a component
* switch to Imported.clamp_dates/4
* reprocess tables when imports are added
* recompute cutoff_date on each call
* actually use clamped_date_range on submit
* add warning message
* add expiry rules to buckets in make minio
* add site_id to imports notifications and use it in csv_importer
* try/catch safer
* return :ok
* date range is not available when no uploads
* improve ui and warning messages
* use Generic.notice
* fix flaky exports test
* begin tests
* Improve `Importer` notification payload shape
---------
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* encode/decode date range in filenames
* Update lib/plausible/imported/csv_importer.ex
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Update lib/plausible/imported/csv_importer.ex
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* drop unused functions
* send failure email if there is no data to export
* use PlausibleWeb.Email.mailer_email_from()
* ensure we get dates from minmax date query
---------
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* ui
* fix redirect link
* improve make minio
* use implicit button form for csv export
* add exports_bucket helper
* read S3_EXPORTS_BUCKET
* supply s3_bucket in export_csv job args
* make plausible_minio use unprotected port
* move s3_csv_export queue to base queues
* Update lib/plausible_web/controllers/site_controller.ex
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
---------
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Implement LV date input using flatpickr
* Implement basics of GA4 import (very dirty WIP)
* Split Google HTTP API into UA and GA4 specific parts
* Add a quick way to record GA4 API responses
* Add first GA4 import fixtures with GA4 Data API responses
* Extract GA4 and UA specific logic form Google API
* Extract UA and GA4 specific actions to distinct controllers
* Add integration test for GA4 importer
* Update GA4 fixtures
* Test GA4 API
* Add debug logging and fix paginating through API results in in GA4 import
* Revert "Implement LV date input using flatpickr"
This reverts commit c696f8ee39d5702f27015c09a4f079ca124cc7bb.
* Fix note
* wip
* more env, setup user before packages to avoid them picking our uid
* make entrypoint.sh executable by all again
* apparently it's a best practice to have executables be owned by root
* make entrypoint executable in COPY
* stop writing to /app, write to /tmp if needed
* fewer changes
* system user
* keep same style for multiline commands
* fewer changes
* add changelog entry
* fix group assignment for plausible user
* use gid=999
* no home
* no home
* add gecos
* add plausible user to nogroup instead of creating a custom one
* eh
* fewer changes
* fewer changes
* fewer changes
* use PERSISTENT_CACHE_DIR instead of STORAGE_DIR
* ignore more
* cleanup
* remove hex timeout env var
* use ERL_FLAGS=+JMsingle true in public builds
* fallback to /tmp and nest under /tzdata_data/ for tzdata
---------
Co-authored-by: Cenk Kücük <cenk@plausible.io>
This can cause issues as 1 day after a deploy the tzdata list is updated
from 2021 to 2024. Selecting a timezone thats not supported in 2021 can
then break dashboards temporarily following a deploy.
This can be reverted after https://github.com/plausible/analytics/pull/3811
* add csv importer
* make table validation explicit
* update some docs
* improve docs
* add minio container to ci
* more tests
* eh
* continue
* add passing test
* add failing test
* add config test
* add minio to Makefile
* testcontainers
* remove extra whitespace
* explain the implementation a bit
* account for async deletes in tests
* bounces is UInt32
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
---------
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Replace footer text
* add COPYING.txt file
* Add new logos
* Use new logos in all layouts
* New logos
* Check license key on startup
* Bypass license check when Mix.env == :dev
* Use new logos with smaller wordmarks
* Add generic logo_path/1 function
* Use new favicons everywhere
* Bypass license check in test env
* Use sha256 for license key hash
* Mix.env -> config_env()
* Use Mix.evn at compile time rather than runtime
* Mix format
---------
Co-authored-by: Uku Taht <uku.taht@gmail.com>
* Clean up references to no longer active `google_analytics_imports` Oban queue
* Stub CSV importer
* Add SiteImport schema
* Rename `Plausible.Imported` module file to match module name
* Add `import_id` column to `Imported.*` CH schemas
* Implement Importer behavior and manage imports state using new entities
* Implement importer callbacks and maintain site.imported_data for UA
* Keep imports in sync when forgetting all imports
* Scope imported data queries to completed import IDs
* Mark newly imported data with respective import ID
* Clean up Importer implementation a bit
* Test querying legacy and new imported data
* Send Oban notifications on import worker failure too
* Fix checking for forgettable imports and remove redundant function
* Fix UA integration test
* Change site import source to atom enum and add source label
* Add typespecs and reduce repetition in `Plausible.Imported`
* Improve documentation and typespecs
* Add test for purging particular import
* Switch email notification templates depending on import source
* Document running import synchronously
* Fix UA importer args parsing and ensure it's covered by tests
* Clear `site.stats_start_date` on complete import to force recalculation
* Test Oban notifications (h/t @ruslandoga)
* Purge stats on import failure right away to reduce a chance of leaving debris behind
* Fix typos
Co-authored-by: hq1 <hq@mtod.org>
* Fix another typo
* Refactor fetching earliest import and earliest stats start date
* Use `Date.after?` instead of `Timex.after?`
* Cache import data in site virtual fields and limit queried imports to 5
* Ensure always current `stats_start_date` is used
* Work around broken typespec in Timex
* Make `SiteController.forget_imported` action idempotent
* Discard irrecoverably failed import tasks
* Use macros for site import statuses
There's also a fix ensuring only complete imports are considered
where relevant - couldn't isolate it as it was in a common hunk
* Use `import_id` as worker job uniqueness criterion
* Do not load imported stats data in plugins API context
---------
Co-authored-by: hq1 <hq@mtod.org>
* Simplify caches config
The intervals were proven to never change really,
and previous shape made them not very discoverable either.
We'll look into a more declarative setup.
* Aim for more declarative supervision tree setup
* Generalize `Plausible.Cache`
This makes the `Site.Cache` module implement the specifics,
leaving the common bits reusable for upcoming cache processes.
* Generalize `Plausible.Cache` warmers
* Fix typos
* Revert "Remove 0-sized queue"
This reverts commit 6d229b3f70.
* Revert "Temporarily remove notification cron worker (#3732)"
This reverts commit 447e3929cb.
* Revert "Temporarily disable accept_traffic_until actions (#3730)"
This reverts commit 58afe3376f.
* Send accept_traffic_until notifications at 8 UTC rather than 5
* Add option for dry-run
* Expose dry_run in a dedicated function
* Move imported tables schemas to separate modules outside Google ns
* Move buffer for imports to Imported ns
* fix schema newlines
* Extract UA import processing and persistence
* Decouple analytics worker implementation from UA
* Rename env variable for import buffer size
* Preserve old import queue until release
* Update communication
* Remove an unreachable function (mistyped)
* [migration] Make accept_traffic_until a date
* Fix typo
* Set `accept_traffic_until` when creating a site
* Update sites `accept_traffic_until` on subscription change
* Add a note to yearly cancellation notification
* Rephrase annual e-mail for clarity
* Pass the small build test
* Add email notifications
* Fixup
* Implement `accept_traffic_until` notification worker
* Fixup - no need to test this for small build
* Update moduledoc
* Move moduletag
* s/sent_at/sent_on
* Use WHERE NOT EXISTS instead of LEFT JOIN
* Use upsert when tracking notifications sent
* Store sent marker before actually sending notification
* Prefer to keep `accept_traffic_until` on the user record
This gives us a single source of truth, addresses cases like
ownership transparently, simplifies the code and enables CRM toggles.
The only downside is that there's another join performed in the
Sites.Cache full refresh - in this case, small refreshes are
skipped - but this is fine, since the traffic will be let in
anyway.
* Expose `accepted_traffic_until` in the CRM
* Update lib/plausible/auth/user.ex
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Preload owner in CRM
* Use the offset parameter in trial over e-mail contents
* Format
* Harden cache test
---------
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Disable super-admin checks on small build
* Mute a test writing to stdout
* Move sampling outside of small build
* Convert waiting_first_pageview to heex and stop relying on env vars
* Set site limit unlimited on small build
* Stop relying on app env to get trial expiry
* Remove custom domains - including migration
* Remove is_selfhosted from layout view
* Quota fixup
* Stop relying on app env for self hosted registration
* Stop relying on app env for pass reset success
* Apply on_trial? check only on full build
* Update templates relying on app env
* Adjusts auth controller tests for small build
* Trial fixup
* Fixup
* Stop relying on app env
* Rest of the fsckn owl
* Update typespecs
* Fix dialyzer warning
* Remove unused module
* Credo + format
* GeoIP is not, for full build
* Use `small_build?()` where applicable
* Implement bypassing FirstLaunchPlug without insertions
* Get Marko's patch de58a18a85
* Test is-dbip=false presence
* Fix typespec
* Remove future hardcodes
* Handle `nil` from `Plausible.Geo.database_type()`
* Remove XXX marker
* Use one typespec for two clauses
* Introduce `MIX_ENV=small_dev`
* Revert "Use one typespec for two clauses"
This reverts commit 8d8cd21764.
* Update applications
* Clone community config
* Move modules to experimental dir
* Update runtime config
* Apply first set of compile-time conditionals
* Move funnel schemas to experimental
* Make funnel schema-less build compile
* Use experimental/lib for elixir code
* Move JS funnels to experimental
* Clean up conditional rendering
* Tidy up the pipeline
* Make two builds pass tests without warnings
* Reuse existing dotenvs
* Do a bunch of renames
* Clean up naming
* Run secondary CI
* Update router
* Remove RewriteFunnelDupes migration
Tests were disabled already and it was a one-off shot
* Fixup quota mixins
* Add moduledoc
* Change MIX_ENV for seconary test run
* Skip crm on small
* !fixup
* Exclude flags pipeline
* Update lib/plausible_web/controllers/stats_controller.ex
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
---------
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Enable JSON log formatting
if `LOG_FORMAT=json` is set, the app will start logging
JSON-formatted messages. By the way, the Repo :loggers configration
was removed since it's been already deprecated by Ecto v3
(https://hexdocs.pm/ecto/changelog.html#deprecations-4).
* Update changelog
* Bump deps
* Bump stack
* Fix deprecation warnings
* Fix VCR cassettes mismatch due to OTP-18414
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Format & fix flaky tests
* Handle raw IPv4 hostnames; test public suffix TLD
* Configure locus db cache_dir
So that maxmind unavailability doesn't affect
application startup. PERSISTENT_CACHE_DIR env var is used
to point locus at the GeoIP DB file.
* WIP: Remove ExVCR
* Fix test env config
* Fixup exvcr
* Remove exvcr from deps
* Add convert script
* Remove exvcr cassettes
* Remove convert script
* Rename test
* Update moduledoc
* Update dockerfile
* Bump CI cache
* Tag more slow tests, why not?
* Use charlist for locus cache option
* Pin nodejs
* Merge google tests, make them async
---------
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Add SSO link with signed JWT token
* Falls back to Nolt URL without SSO if token cannot be generated
* Add profile image (gravatar) to Nolt SSO link
* Improve navbar dropdown
* Add 'contact support' link to nav dropdown
* Add CSS rule to prevent horizontal jumps
* Dark mode styling
* Close dropdown when link is clicked
* Clarify links in dropdown
* Clarify CSS comment
* Use Alpine.data() over window
* Rename suggestions_dropdown -> combo-box
* Mix format
* Make logout link look good on dark mode
* Use proxy for gravatar
* Do not use Gravatar proxy in self-hosted
* Changelog
* Add Github Repo link to nav dropdown
* Make dialyzer happy
* Add proxy for Gravatar
* Update assets/css/app.css
Co-authored-by: hq1 <hq@mtod.org>
* Update lib/plausible_web/controllers/avatar_controller.ex
Co-authored-by: hq1 <hq@mtod.org>
* Fix alpine <> Liveview integration
---------
Co-authored-by: hq1 <hq@mtod.org>
* Refactor email verification codes generation to avoid predictability
* Improve `Site.Memberships.any?` slightly
* Update tests
* Fix seeds
* Use `expired?` predicate for checking verification code validity in tests
* Store verification code as string in database to avoid unnecessary int casting