Commit Graph

2454 Commits

Author SHA1 Message Date
dependabot[bot]
b298e0e1b5
Bump actions/setup-node from 3 to 4 (#3468)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 4.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-31 14:58:18 -03:00
Vini Brasil
3b28a8d418
Warn user about Stats API when downgrading (#3471)
* Warn user about Stats API when downgrading

* Update test/plausible/billing/quota_test.exs

Co-authored-by: RobertJoonas <56999674+RobertJoonas@users.noreply.github.com>

---------

Co-authored-by: RobertJoonas <56999674+RobertJoonas@users.noreply.github.com>
2023-10-31 14:57:21 -03:00
RobertJoonas
3c76053c3f
ignore only pv limit exceeded on subscribe (#3470) 2023-10-30 17:06:51 +00:00
RobertJoonas
8cc7bce689
Restrict subscribing to a plan when exceeding its limits + warning for losing feature access (#3461)
* fix the styling of the red text notice under checkout link

* avoid some code repetition

* simplify rendering the change_plan_link

* refactor disabling checkout link and showing disabled message

* disable change plan and upgrade link when exceeding pageview limit

* disable checkout when exceeding team member limit

* disable checkout when site limit exceeded

* extract checkout related code in a separate function

* stick to a single order of features

* losing features warning

* fix back link from change-plan-preview

* create Quota.exceeded_limits function

* restrict subscribing with exceeded limits on the API level too

* use with instead of case

Co-authored-by: Vini Brasil <vini@hey.com>

* use :map type instead of :any for user

Co-authored-by: Vini Brasil <vini@hey.com>

* create Quota.usage function

---------

Co-authored-by: Vini Brasil <vini@hey.com>
2023-10-26 18:20:38 +03:00
dependabot[bot]
0c8b3d7992
Bump postcss from 8.4.29 to 8.4.31 in /assets (#3398)
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.29 to 8.4.31.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.29...8.4.31)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-25 09:01:59 -03:00
dependabot[bot]
7312598b4b
Bump @babel/traverse from 7.21.5 to 7.23.2 in /assets (#3431)
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.21.5 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-25 09:01:33 -03:00
dependabot[bot]
f4cbefbcb4
Bump eslint-plugin-playwright from 0.16.0 to 0.18.0 in /tracker (#3451)
Bumps [eslint-plugin-playwright](https://github.com/playwright-community/eslint-plugin-playwright) from 0.16.0 to 0.18.0.
- [Release notes](https://github.com/playwright-community/eslint-plugin-playwright/releases)
- [Changelog](https://github.com/playwright-community/eslint-plugin-playwright/blob/main/CHANGELOG.md)
- [Commits](https://github.com/playwright-community/eslint-plugin-playwright/compare/v0.16.0...v0.18.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-playwright
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-25 09:00:54 -03:00
Vini Brasil
ad05af08a4
Check for limits and features used by site before transferring ownership (#3445)
* Simplify team_member_usage query

* Check limits before transferring ownership

* Extract invite creation to dedicated service module

* Simplify team member usage query

* Remove unnecessary distinct clause

* Delegate CreateInvitation via Memberships
2023-10-25 09:00:31 -03:00
RobertJoonas
a226773da1
Legacy plans (#3455)
* replace unlisted plans with legacy plans

...and add a legacy plan that has an existing subscriber in Paddle. All
legacy plans are considered generation 1 - meaning that when a user on
one of these plans and they'll go to the upgrade page, then the listed
plans will be v1 for Growth and v3 for Business.

* remove redundant plans_sandbox function

* remove the unused 'scope' argument from Plans.find

* remove unused plan

* add basic test coverage for legacy plans

* add another plan with an existing active subscriber (fix another bug)
2023-10-25 13:46:55 +03:00
Marko Saric
9798a80a5a
Copy changes (#3460) 2023-10-25 13:44:59 +03:00
Uku Taht
c075a1b149
Fix feedback link (#3452) 2023-10-24 12:16:33 +03:00
hq1
117eef000d
Upgrade Erlang/Elixir stack (#3454)
* 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>
2023-10-24 10:33:48 +02:00
RobertJoonas
2ada3d700f
List plan benefits on the new upgrade page (#3444)
* change team member limits for new v4 plans

* duplicate business plans with unlimited team members

We need to do this because we want grandfathered users to have unlimited
team members on business plans as well. Otherwise we'd have to build
overrides on the subscription level when checking the limit.

* refactor generating plan structs

* move Plan module into a separate file

* remove not needed conditions

* add generation field to plans

* sync the sanbox plan limits and features with plan generations

* implement displaying plan benefits

* add grandfathering notice

* plug in the real v3 business plan IDs

* optimize N/A text color for darkmode

* use String.to_existing_atom instead

Co-authored-by: Vini Brasil <vini@hey.com>

* Remove the unnecessary part of a comment

Co-authored-by: Vini Brasil <vini@hey.com>

* make the Plan.new function simpler

* use exlamation marks

---------

Co-authored-by: Vini Brasil <vini@hey.com>
2023-10-23 19:42:00 +03:00
hq1
957138a8ec
Plugins API: handle Revenue Goals creation wrt Business Tier (#3440)
* Plugins API: handle Revenue Goals creation wrt Business Tier

* Update bulk goal creation

* Update test/plausible_web/plugins/api/controllers/goals_test.exs

Co-authored-by: Vini Brasil <vini@hey.com>

* Use growth_subscription factory

---------

Co-authored-by: Vini Brasil <vini@hey.com>
2023-10-18 14:14:45 +02:00
hq1
19b2239eb9
Track tokens usage (#3438)
* Migration: track last seen usage for Plugins API Tokens

* Track and interpret Token.last_seen_at

* Display last used

* Order tokens by inserted date, rather than UUID :clown:

* s/Last seen/Last used in the UI

* Test for "Last used" column presence

* Fix table layout for very long descriptions

* Update lib/plausible/plugins/api/tokens.ex

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update lib/plausible/plugins/api/token.ex

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update test/plausible/plugins/api/token_test.exs

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* s/last_seen_at/last_used_at

* Update lib/plausible_web/live/plugins/api/settings.ex

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* fixup

* Document reasoning behind 5m windows

* s/last_seen/last_used

* Mute credo

---------

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
2023-10-18 14:14:30 +02:00
hq1
2cc80ebd7a
Integrations Settings section (#3427)
* Extend the Tokens context module

* Extract GA Import to separate component

* Extract Search Console settings to separate component

* Remove Search Console from the router

* Stop counting imported pageviews in general settings

* Remove search console controller action

* Add settings_integrations controller action

* Fix remaining redirects

* Add Integrations route

* Replace SC sidebar item with Integrations

* Update site controller tests

* Implement Plugins API Tokens LV

* Apply universal heroicon to docs info links

* Add flash on token creation

* Update CHANGELOG

* Redirect to integrations upon forgetting GA import

* Update moduledocs

* Remove unnecessary wildcards

* WIP: attempt at fixing broken oauth flow

* Fix post-import redirect

* Fixup missing attribute

* Format

* Seed random google auth

* Use example.com for seeded e-mails

* Tweak Google integrations layout

* Remove dangling IO.inspect

* Bugfix: copy to clipboard breaking LV form bindings

* Update lib/plausible/plugins/api/tokens.ex

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update lib/plausible_web/controllers/site_controller.ex

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update lib/plausible_web/live/plugins/api/settings.ex

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update test/plausible/plugins/api/tokens_test.exs

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

---------

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
2023-10-18 14:01:17 +02:00
Adrian Gruntkowski
127a9ef9ba
Document reasoning behind disabling deduplication in import tables (#3439) 2023-10-18 12:05:25 +02:00
Vini Brasil
3b0322670b
Update plans_v4.json with new plans IDs (#3436)
* Update plans_v4.json with new plans IDs

* Fix failing tests

---------

Co-authored-by: RobertJoonas <56999674+RobertJoonas@users.noreply.github.com>
2023-10-18 11:48:47 +03:00
RobertJoonas
7674c94ace
Refactor: Add 'goals' feature to JSON plan files (#3435)
* fix text color in dark mode

* rename a function

* use aliases in quota.ex

* rename a function

* make Goals a similar feature to others but with a free option

* rename a function

* mix format
2023-10-18 11:29:13 +03:00
hq1
52d5fac362
Fixup 4cdf843ad: (#3434)
- migration is irreversible for now,
    likely due to https://github.com/plausible/ecto_ch/issues/81#issuecomment-1624754909
    or maybe https://github.com/plausible/ecto_ch/pull/58/files
  - IO.inspect call removed
2023-10-17 16:07:06 +02:00
Marko Saric
ff66e9b1e4
changing the link to the feedback board 2023-10-17 16:06:56 +02:00
Marko Saric
9e13e20567
fixing the link for feature requests 2023-10-17 16:03:27 +02:00
Vini Brasil
896d78d8fd
Apply feature gates to dashboard queries (#3424)
* Read feature status from Billing.Feature instead of %Site{}

This commit changes data attributes passed to React. Previously the
controller read feature statuses directly from the %Site{} schema. The
Billing.Feature context is aware of the user plan and the features
available.

* Limit funnels internal API based on site owner plan

* Limit props internal API based on site owner plan

* Use site factory in QueryTest

* Limit custom property filter based on site owner plan

* Limit revenue goals queries based on site owner plan
2023-10-17 10:00:00 -03:00
hq1
9b912f3d89
Fix liveview (#3433) 2023-10-17 13:15:27 +02:00
Adrian Gruntkowski
4cdf843ade
Disable deduplication for improted_* tables in CH (#3429)
* Disable deduplication for improted_* tables in CH

* Make migration cluster-aware

* Bump cache to avoid problems

* Fix cache dump

* Remove cache bump
2023-10-17 12:51:13 +02:00
Uku Taht
fd8a9529f9
Choose plan styling (#3399)
* Update styling for Choose Plan page

* Make it look good on mobile

* Update tests

* Remove unnecessary assign

* Optimize for dark mode

* Change order or interval picker and slider on mobile

* Format

---------

Co-authored-by: RobertJoonas <56999674+RobertJoonas@users.noreply.github.com>
2023-10-17 13:36:25 +03:00
hq1
e12ea9701d
Fix master build (#3432) 2023-10-17 12:16:04 +02:00
Uku Taht
d7cd719d4f
Use default Phoenix.LiveView.Socket (#3404)
* Use default Phoenix.LiveView.Socket

* Pull socket definition highed in Endpoint config

* Simplify runtime plug session
2023-10-17 12:03:21 +03:00
Uku Taht
97b24c0492
Nolt sso (along with a better nav dropdown) (#3395)
* 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>
2023-10-17 12:01:27 +03:00
hq1
99efb93082
No longer require domain to seek Plugins API Tokens (#3409)
* No longer require domain to seek Plugins API Tokens

* Accept raw token only
2023-10-16 13:22:09 +02:00
Adrian Gruntkowski
70c001099d
Improve and simplify email verification codes generation (#3407)
* 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
2023-10-16 13:21:18 +02:00
Adrian Gruntkowski
87f7729cf9
Add email_activation_codes table (#3426)
* Add email_activation_codes table

* Change code column in migration to string
2023-10-16 12:56:36 +02:00
Marko Saric
d338980dc5
new copy for the cancellation email (#3422)
* Update cancellation_email.html.eex

* changing the subject too

* Fix broken test

---------

Co-authored-by: Vinicius Brasil <vini@hey.com>
2023-10-13 14:14:42 -03:00
dependabot[bot]
d6b5b2939b
Bump @playwright/test from 1.37.1 to 1.39.0 in /tracker (#3415)
Bumps [@playwright/test](https://github.com/microsoft/playwright) from 1.37.1 to 1.39.0.
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](https://github.com/microsoft/playwright/compare/v1.37.1...v1.39.0)

---
updated-dependencies:
- dependency-name: "@playwright/test"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-13 13:41:03 -03:00
Adrian Gruntkowski
f0c749ad70
Implement direct site ownership transfer without invite via CRM (#3416) 2023-10-13 13:37:58 -03:00
RobertJoonas
313bfa0558
remove wrong FF condition (#3417) 2023-10-12 16:16:26 +03:00
Vini Brasil
c0fe2a3996
Implement Stats API feature gate (#3411)
* Include ApiKey functions in Auth context

* Make feature notice work without %Site{}

Previously the extra feature notice required a %Site{} in order to check
the owner plan. However, not every feature is scoped by site, for
example the Stats API. For features like this, a %User{} is required,
and not a %Site{}.

This commit replaces the `:site` param with `:billable_user`, which is
common to both site and user-scoped features.

* Add stats_api to the list of extra features

* Limit API Key creation based on user plan
2023-10-11 17:24:16 -03:00
Adrian Gruntkowski
192aefc493
Fix email update flow for selfhosted setup with verification disabled (#3408) 2023-10-11 15:12:57 +02:00
Vini Brasil
303b3509f7
Feature gates (#3401)
This pull request implements limits to funnels, revenue goals and custom props based on the site owner plan. It extends the current "premium feature" notice to account for the new plans, trials and the on-going private preview. Stats API is not in the context of this pull request, but will be implemented likewise.
2023-10-11 09:40:01 -03:00
Marko Saric
90cb7cdef8
Some changes to the onboarding email copy (#3392)
* Update site_setup_success_email.html.eex

* Update check_stats_email.html.eex

* Update trial_one_week_reminder.html.eex

---------

Co-authored-by: RobertJoonas <56999674+RobertJoonas@users.noreply.github.com>
2023-10-11 09:38:40 -03:00
dependabot[bot]
6c018f884a
Bump eslint from 8.48.0 to 8.51.0 in /tracker (#3402)
Bumps [eslint](https://github.com/eslint/eslint) from 8.48.0 to 8.51.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.48.0...v8.51.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-11 09:37:41 -03:00
Adrian Gruntkowski
439c5014d4
Trigger email reverification on change (#3388)
* Implement PoC for email reverification flow on update

* Improve user settings form and email change validation

* Expose `previous_email` in Kaffy CRM

* Improve plugs setup and remove dead action from AuthController

* Fix seeds

* Extract predicate query functions from AuthController

* Add tests

* Update CHANGELOG.md

* Rename `has_any_sites?` to `Memberships.any?` and `has_any_memberships?`

* Improve flash message on cancelling email change

* Cover one more test case for email update
2023-10-11 10:25:00 +02:00
Adrian Gruntkowski
33b5e69c64
Add previous_email column to users (#3406) 2023-10-11 10:03:35 +02:00
RobertJoonas
3d2f356ba7
Refactor enterprise plan upgrade and change-plan actions (#3397)
* rename enterprise?/1 function

* change link text to Upgrade when subscription deleted

* extract paddle_button and paddle_script components

* create a new upgrade-to-enterprise-plan page

* extract upgrade_link component

* rename function

* link to enterprise plan upgrade page from settings

...if the user has an enterprise plan configured

* fetch enterprise plan price on the new page

* add change_enterprise_plan functionality on the new page

* render existing change_enterprise_plan_contact_us.html

...when subscribed to latest configured enterprise plan

* rename vars and extract resumable? fn

* remove dead billing route

* small test refactor: extract convenience fn

* add tests for...

...restricting paused and past_due subscription access to the new
enterprise plan page.

1. redirect to /settings from the controller action
2. hiding the change-plan link from the user settings

* implement redirect to /settings

* hide the enterprise upgrade/change-plan link

* add tests for a deleted enterprise subscription

* plug in the new controller action and delete dead code

* optimize for dark mode

* fix compile warning

* credo fix

* display N/A instead of crash when price nil

* change subscription.status type to Ecto.Enum

Also, create a new `Subscription.Status` module that exposes macros to
return the used atom values (prevent typos at compiletime).

* fix bug (@conn not available anymore)

* use Routes.billing_path where applicable

* add a status() type

* silence credo

* refactor suggestion from review

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Remove the __using__ macro from Subscription.Status

... instead be explicit about requires and aliases and also order
the use, import, require, and alias clauses according to
https://github.com/christopheradams/elixir_style_guide#module-attribute-ordering

* drop the virtual Enteprise 'price_per_interval' field

* apply review suggestion to make the code more DRY

* use dot syntax to fetch current user in new controller actions

* fix formatting

---------

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
2023-10-10 20:35:17 +03:00
Adrian Gruntkowski
dec193e904
Make FixBrokenGoals migration idempotent (#3405)
* Make FixBrokenGoals migration idempotent

The migration in question was renamed in order to fix order of executing migrations when run
from the ground up (via https://github.com/plausible/analytics/pull/3378).

As a side effect, it's executed again on databases that had it applied earlier, with
a different timestamp prefix.

As this migration is safe to run multiple times, it was modified to make forward
migration work gracefully when constraint already exists.

* Add `pending-migrations.sh` release script
2023-10-10 14:13:11 +02:00
Adrian Gruntkowski
21297b666f
Add constraint enforcing at most one owner membership per site (#3403) 2023-10-10 11:43:38 +02:00
Adrian Gruntkowski
842bbb7995
Fix invalid subscription preload in SiteLocker email submission routine (#3400) 2023-10-06 00:53:55 +02:00
hq1
0007c0c108
Plugins API: 2nd pass with Goals resource + SharedLinks schema changes (#3396)
* Remove "Context" namespace level

* Change Goal string representation

* Alias Schemas in Plugin API Test Case template

* Update schema & tests for SharedLink resource

* Update Goals interface

- make it possible to create revenue goals
- extract "for site" query to a standalone function

* Fixup typespecs

* Alias Errors module in OpenAPI controllers

* Add missing goals test

* Implement Goals Plugins API resource

* Add extra test to confirm changeset error propagation

* Mute credo

* Fix typos

* Handle changeset traversal in `Errors`

* Use upserts in `Goals.find_or_create`

* Extract touch_site! to Site.Cache, address credo, improve code docs

* Apply formatting

* Remove unused inner join

* Update test/plausible_web/plugins/api/controllers/goals_test.exs

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update test/plausible_web/plugins/api/controllers/goals_test.exs

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update test/plausible_web/plugins/api/controllers/goals_test.exs

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update test/plausible_web/plugins/api/controllers/goals_test.exs

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update test/plausible_web/plugins/api/controllers/goals_test.exs

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update error message on revenue goal currency clash

* Remove unused code

---------

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
2023-10-05 11:54:18 +02:00
Adrian Gruntkowski
d608fec903
Improve domain cleanup on site creation (#3393) 2023-10-04 12:32:27 +02:00
Adrian Gruntkowski
296637dc18
Ensure that User.password_strength/1 always returns a value (#3389) 2023-10-03 13:32:07 +02:00