Skip to content

feat: Add session claims feature #209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 76 commits into from
Sep 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
abba205
feat: Add primitive claim and its tests for session grants
KShivendu Jul 14, 2022
349596a
feat: Add more functions related to session claims
KShivendu Jul 17, 2022
ed3a1cb
test: Add more tests for session claim features
KShivendu Jul 18, 2022
6d297b0
feat: Wrap up features and tests related to basic session claims
KShivendu Jul 21, 2022
9a0886c
feat: Refactor session claims and tests
KShivendu Jul 22, 2022
ef1b610
Merge pull request #211 from supertokens/feat/session-grants-refactor
KShivendu Jul 25, 2022
b984f64
test: Implement AsyncMock if not available and fix failing tests
KShivendu Jul 26, 2022
597415c
test: Fix minor bug in @min_api_version test wrapper
KShivendu Jul 26, 2022
f74e97b
ci: Add debugging support in GH actions using tmate
KShivendu Jul 26, 2022
4950367
ci: Run tmate only if tests fail
KShivendu Jul 26, 2022
ccf3dc6
fix: Import missing SessionRecipe to fix test failures
KShivendu Jul 26, 2022
0dc1819
ci: Trigger tmate for debugging before tests if debug mode is enabled
KShivendu Jul 26, 2022
1493aeb
test: Fix session claims test failures
KShivendu Jul 27, 2022
76b1cc3
fix: Fix test failures for python3.7, use fixtures, and fix bugs
KShivendu Jul 28, 2022
f084a51
refactor: Extract SessionClaim related classes for easier inheritance…
KShivendu Jul 28, 2022
583e820
refactor: Clean up session claims tests
KShivendu Jul 28, 2022
45abb80
fix: Add pytest-mock to dev-requirements.txt
KShivendu Jul 28, 2022
9f981c9
fix: Changes suggested in PR feedback
KShivendu Jul 31, 2022
e932be8
refactor: Make ClaimValidationResult an object instead of dict
KShivendu Aug 2, 2022
54e2736
feat: Changes suggested in feedback
KShivendu Aug 3, 2022
a7e4b6a
feat: Add and use email verification claim
KShivendu Aug 7, 2022
918e15f
feat: Add and use email verification claim
KShivendu Aug 7, 2022
07fe952
fix: Fix lint errors and make email verification claims usable
KShivendu Aug 8, 2022
29d7cee
refactor: Use email veriifcation claim in thirdparty recipe
KShivendu Aug 9, 2022
6957000
refactor: Run black on tp recipe and use ev claim in pless recipe
KShivendu Aug 9, 2022
44d0f3a
refactor: Remove email verification features from thirdpartyemailpass…
KShivendu Aug 9, 2022
720f593
refactor: Remove email verification features from thirdpartypasswordl…
KShivendu Aug 9, 2022
e31b60d
refactor: Clean up usages of email verification in other recipes in f…
KShivendu Aug 10, 2022
0834fe5
refactor: Fix circular dependency error in emailverification recipe a…
KShivendu Aug 10, 2022
34e492a
test: Fix test failures related to tpep recipe
KShivendu Aug 10, 2022
1586251
refactor: Allow emailverification init without directly using ParentR…
KShivendu Aug 10, 2022
10395c4
tests: Fix test failures in tppless email delivery
KShivendu Aug 10, 2022
c26242e
feat: Changes suggested in feedback
KShivendu Aug 11, 2022
e77328e
feat: Apply claims on access_token_payload when calling create_new_se…
KShivendu Aug 11, 2022
27282d4
changes based on feedback
KShivendu Aug 17, 2022
3df9f16
Remove get_link_domain_and_path function and ev logic from other recipes
KShivendu Aug 17, 2022
dc9c3be
changes suggested in PR feedback
KShivendu Aug 17, 2022
0ac965c
test invalid claims response with and without reason
KShivendu Aug 17, 2022
3663a1d
fix test failure
KShivendu Aug 17, 2022
e58cb87
feat: Changes suggested in feedback
KShivendu Sep 1, 2022
63eb59b
Merge branch 'feat/session-grants' into feat/ev-claim
KShivendu Sep 1, 2022
619ac25
feat: Changes suggested in feedback
KShivendu Sep 1, 2022
5b36b16
refactor: Remove ParentRecipeEmailVerificationConfig
KShivendu Sep 1, 2022
01c2609
test: Fix failing tests
KShivendu Sep 1, 2022
6fc90c6
refactor: Remove irrelevant comment
KShivendu Sep 1, 2022
a038414
Merge pull request #215 from supertokens/feat/ev-claim
rishabhpoddar Sep 5, 2022
200e4c6
feat: Most of requested changes except the last two
KShivendu Sep 5, 2022
dac30f0
Merge branch 'feat/session-claim-remaining' into feat/session-grants
KShivendu Sep 5, 2022
28392ee
feat: More of requested changes
KShivendu Sep 5, 2022
2dca9c0
refactor:remaining changes
KShivendu Sep 6, 2022
5eac706
feat: complete remaining items
KShivendu Sep 6, 2022
b103949
feat: changes suggested in feedback
KShivendu Sep 7, 2022
c18ba05
feat: More of requested changes
KShivendu Sep 9, 2022
58255c1
feat: requested changes
KShivendu Sep 9, 2022
f35003c
feat: last changes
KShivendu Sep 9, 2022
aa37fe3
feat: remove commet
KShivendu Sep 9, 2022
e438cdf
feat: remove commet
KShivendu Sep 9, 2022
9879067
Merge branch '0.10' into feat/session-grants
rishabhpoddar Sep 10, 2022
b013a5d
makes user context optional in syncio exposed functions for user roles
rishabhpoddar Sep 10, 2022
0322472
feat: last changes
KShivendu Sep 12, 2022
1c395a7
refactor: Serialize ClaimValidationError in default implementation of…
KShivendu Sep 12, 2022
9138a41
test: Fix failing tests
KShivendu Sep 12, 2022
0e3fd33
fix: emailverification syncio
KShivendu Sep 12, 2022
a000d3c
Merge pull request #221 from supertokens/feat/session-grants-new
rishabhpoddar Sep 12, 2022
8f21297
test: session claims fix failing tests
KShivendu Sep 12, 2022
23aacfc
test: Fix failing tests
KShivendu Sep 13, 2022
dc7390d
test: add tests for userroles claims
KShivendu Sep 13, 2022
af39f58
test: Fix failing tests
KShivendu Sep 13, 2022
87595a4
feat: CHANGELOG
KShivendu Sep 13, 2022
7065aed
fix: fix changelog
KShivendu Sep 13, 2022
aa1d35f
feat: update fdi version
KShivendu Sep 13, 2022
ba3f774
test: Add tests for primitive array claim
KShivendu Sep 13, 2022
e3fd8c9
feat: update fdi version
KShivendu Sep 13, 2022
984dfc4
test: Fix failing tests
KShivendu Sep 14, 2022
0283c00
feat: example app update for emailverification
KShivendu Sep 14, 2022
df5994f
Merge pull request #223 from supertokens/test/session-claims
rishabhpoddar Sep 14, 2022
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: 6 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,10 @@ jobs:
run: cd ../supertokens-root && ./loadModules
- name: Setting up supertokens-root test environment
run: cd ../supertokens-root && bash ./utils/setupTestEnvLocal
- name: Debugging with tmate
if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }}
uses: mxschmitt/[email protected]
with:
sudo: false
- name: Run tests
run: make test
run: make test
159 changes: 159 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,165 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [unreleased]

### Changes

- Made the `email` parameter option in `unverify_email`, `revoke_email_verification_tokens`, `is_email_verified`, `verify_email_using_token`, `create_email_verification_token` of the `EmailVerification` recipe.

### Added

- Added support for session claims with related interfaces and classes.
- Added `on_invalid_claim` optional error handler to send InvalidClaim error responses.
- Added `INVALID_CLAIMS` (`InvalidClaimError`) to `SessionErrors`.
- Added `invalid_claim_status_code` optional config to set the status code of InvalidClaim errors.
- Added `override_global_claim_validators` as param of `get_session` and `verify_session`.
- Added `merge_into_access_token_payload` to the Session recipe and session objects which should be preferred to the now deprecated `update_access_token_payload`.
- Added `EmailVerificationClaim`, `UserRoleClaim` and `PermissionClaim`. These claims are now added to the access token payload by default by their respective recipes.
- Added `assert_claims`, `validate_claims_for_session_handle`, `validate_claims_in_jwt_payload` to the Session recipe to support validation of the newly added claims.
- Added `fetch_and_set_claim`, `get_claim_value`, `set_claim_value` and `remove_claim` to the Session recipe to manage claims.
- Added `assert_claims`, `fetch_and_set_claim`, `get_claim_value`, `set_claim_value` and `remove_claim` to session objects to manage claims.
- Added session to the input of `generate_email_verify_token_post`, `verify_email_post`, `is_email_verified_get`.
- Adds default userContext for verifySession calls that contains the request object.

### Breaking Changes
- Changed `sign_in_up` third party recipe function to accept just the email as `str` (removed `email_verified: bool`).
- The frontend SDK should be updated to a version supporting session claims!
- supertokens-auth-react: >= 0.25.0
- supertokens-web-js: >= 0.2.0
- `EmailVerification` recipe is now not initialized as part of auth recipes, it should be added to the `recipe_list` directly instead using `emailverification.init()`.
- Email verification related overrides (`email_verification_feature` attr of `override`) moved from auth recipes into the `EmailVerification` recipe config.
- Email verification related configs (`email_verification_feature` attr) moved from auth recipes into the `EmailVerification` config object root.
- ThirdParty recipe no longer takes `email_delivery` config. use `emailverification` recipe's `email_delivery` instead.
- Moved email verification related configs from the `email_delivery` config of auth recipes into a separate `EmailVerification` email delivery config.
- Updated return type of `get_email_for_user_id` in the `EmailVerification` recipe config. It should now return an object with status.
- Removed `get_reset_password_url`, `get_email_verification_url`, `get_link_domain_and_path`. Changing these urls can be done in the email delivery configs instead.
- Removed `unverify_email`, `revoke_email_verification_tokens`, `is_email_verified`, `verify_email_using_token` and `create_email_verification_token` from auth recipes. These should be called on the `EmailVerification` recipe instead.
- Changed function signature for email verification APIs to accept a session as an input.
- Changed Session API interface functions:
- `refresh_post` now returns a Session container object.
- `sign_out_post` now takes in an optional session object as a parameter.

### Migration
Before:
```python
from supertokens_python import init, SupertokensConfig, InputAppInfo
from supertokens_python.recipe import emailpassword
from supertokens_python.recipe.emailverification.utils import OverrideConfig

init(
supertokens_config=SupertokensConfig("..."),
app_info=InputAppInfo("..."),
framework="...",
recipe_list=[
emailpassword.init(
# these options should be moved into the EmailVerification config:
email_verification_feature=emailpassword.InputEmailVerificationConfig("..."),
override=emailpassword.InputOverrideConfig(
email_verification_feature=OverrideConfig(
# these overrides should be moved into the EmailVerification overrides
"..."
)
),
),
],
)
```

After the update:

```python
from supertokens_python import init, SupertokensConfig, InputAppInfo
from supertokens_python.recipe import emailpassword, emailverification

init(
supertokens_config=SupertokensConfig("..."),
app_info=InputAppInfo("..."),
framework="...",
recipe_list=[
emailverification.init(
"...", # EmailVerification config
override=emailverification.OverrideConfig(
# overrides
"..."
),
),
emailpassword.init(),
],
)
```

#### Passwordless users and email verification

If you turn on email verification your email-based passwordless users may be redirected to an email verification screen in their existing session.
Logging out and logging in again will solve this problem or they could click the link in the email to verify themselves.

You can avoid this by running a script that will:

1. list all users of passwordless
2. create an emailverification token for each of them if they have email addresses
3. user the token to verify their address

Something similar to this script:

```python
from supertokens_python import init, SupertokensConfig, InputAppInfo
from supertokens_python.recipe import passwordless, emailverification, session
from supertokens_python.recipe.passwordless import ContactEmailOrPhoneConfig


from supertokens_python.syncio import get_users_newest_first
from supertokens_python.recipe.emailverification.syncio import create_email_verification_token, verify_email_using_token
from supertokens_python.recipe.emailverification.interfaces import CreateEmailVerificationTokenOkResult

init(
supertokens_config=SupertokensConfig("http://localhost:3567"),
app_info=InputAppInfo(
app_name="SuperTokens Demo",
api_domain="https://api.supertokens.io",
website_domain="supertokens.io",
),
framework="fastapi",
recipe_list=[
emailverification.init("REQUIRED"),
passwordless.init(
contact_config=ContactEmailOrPhoneConfig(),
flow_type="USER_INPUT_CODE_AND_MAGIC_LINK",
),
session.init(),
],
)

def verify_email_for_passwordless_users():
pagination_token = None
done = False

while not done:
res = get_users_newest_first(
limit=100,
pagination_token=pagination_token,
include_recipe_ids=["passwordless"]
)

for user in res.users:
if user.email is not None:
token_res = create_email_verification_token(user.user_id, user.email)
if isinstance(token_res, CreateEmailVerificationTokenOkResult):
verify_email_using_token(token_res.token)

done = res.next_pagination_token is None
if not done:
pagination_token = res.next_pagination_token

verify_email_for_passwordless_users()
```

#### User roles

The `UserRoles` recipe now adds role and permission information into the access token payload by default. If you are already doing this manually, this will result in duplicate data in the access token.

- You can disable this behaviour by setting `skip_adding_roles_to_access_token` and `skip_adding_permissions_to_access_token` to true in the recipe init.
- Check how to use the new claims in the updated guide: https://supertokens.com/docs/userroles/protecting-routes


## [0.10.4] - 2022-08-30
## Features:
- Add support for User ID Mapping using `create_user_id_mapping`, `get_user_id_mapping`, `delete_user_id_mapping`, `update_or_delete_user_id_mapping` functions
Expand Down
1 change: 1 addition & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,4 @@ uvicorn==0.18.2
Werkzeug==2.0.3
wrapt==1.13.3
zipp==3.7.0
pytest-mock==3.8.2
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@
get_all_cors_headers,
init,
)
from supertokens_python.recipe import session, thirdpartyemailpassword
from supertokens_python.recipe import (
session,
thirdpartyemailpassword,
emailverification,
)
from supertokens_python.recipe.thirdpartyemailpassword import (
Apple,
Discord,
Expand Down Expand Up @@ -62,6 +66,7 @@ def get_website_domain():
mode="wsgi",
recipe_list=[
session.init(),
emailverification.init("REQUIRED"),
thirdpartyemailpassword.init(
providers=[
Google(
Expand Down
7 changes: 6 additions & 1 deletion examples/with-fastapi/with-thirdpartyemailpassword/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
init,
)
from supertokens_python.framework.fastapi import get_middleware
from supertokens_python.recipe import session, thirdpartyemailpassword
from supertokens_python.recipe import (
session,
thirdpartyemailpassword,
emailverification,
)
from supertokens_python.recipe.session import SessionContainer
from supertokens_python.recipe.session.framework.fastapi import verify_session
from supertokens_python.recipe.thirdpartyemailpassword import (
Expand Down Expand Up @@ -52,6 +56,7 @@ def get_website_domain():
framework="fastapi",
recipe_list=[
session.init(),
emailverification.init("REQUIRED"),
thirdpartyemailpassword.init(
providers=[
Google(
Expand Down
7 changes: 6 additions & 1 deletion examples/with-flask/with-thirdpartyemailpassword/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
init,
)
from supertokens_python.framework.flask import Middleware
from supertokens_python.recipe import session, thirdpartyemailpassword
from supertokens_python.recipe import (
session,
thirdpartyemailpassword,
emailverification,
)
from supertokens_python.recipe.session.framework.flask import verify_session
from supertokens_python.recipe.thirdpartyemailpassword import (
Apple,
Expand Down Expand Up @@ -45,6 +49,7 @@ def get_website_domain():
framework="flask",
recipe_list=[
session.init(),
emailverification.init("REQUIRED"),
thirdpartyemailpassword.init(
providers=[
Google(
Expand Down
2 changes: 1 addition & 1 deletion frontendDriverInterfaceSupported.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"_comment": "contains a list of frontend-driver interfaces branch names that this core supports",
"versions": [
"1.14"
"1.14", "1.15"
]
}
32 changes: 32 additions & 0 deletions supertokens_python/post_init_callbacks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
#
# This software is licensed under the Apache License, Version 2.0 (the
# "License") as published by the Apache Software Foundation.
#
# You may not use this file except in compliance with the License. You may
# obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from typing import Callable, List


class PostSTInitCallbacks:
"""Callbacks that are called after the SuperTokens instance is initialized."""

callbacks: List[Callable[[], None]] = []

@staticmethod
def add_post_init_callback(cb: Callable[[], None]) -> None:
PostSTInitCallbacks.callbacks.append(cb)

@staticmethod
def run_post_init_callbacks() -> None:
for cb in PostSTInitCallbacks.callbacks:
cb()

PostSTInitCallbacks.callbacks = []
3 changes: 0 additions & 3 deletions supertokens_python/recipe/emailpassword/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
exceptions = ex
InputOverrideConfig = utils.InputOverrideConfig
InputResetPasswordUsingTokenFeature = utils.InputResetPasswordUsingTokenFeature
InputEmailVerificationConfig = utils.InputEmailVerificationConfig
InputSignUpFeature = utils.InputSignUpFeature
InputFormField = utils.InputFormField
SMTPService = emaildelivery_services.SMTPService
Expand All @@ -42,14 +41,12 @@ def init(
reset_password_using_token_feature: Union[
utils.InputResetPasswordUsingTokenFeature, None
] = None,
email_verification_feature: Union[utils.InputEmailVerificationConfig, None] = None,
override: Union[utils.InputOverrideConfig, None] = None,
email_delivery: Union[EmailDeliveryConfig[EmailTemplateVars], None] = None,
) -> Callable[[AppInfo], RecipeModule]:
return EmailPasswordRecipe.init(
sign_up_feature,
reset_password_using_token_feature,
email_verification_feature,
override,
email_delivery,
)
7 changes: 3 additions & 4 deletions supertokens_python/recipe/emailpassword/api/implementation.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,9 @@ async def generate_password_reset_token_post(

token = token_result.token
password_reset_link = (
await api_options.config.reset_password_using_token_feature.get_reset_password_url(
user, user_context
)
+ "?token="
api_options.app_info.website_domain.get_as_string_dangerous()
+ api_options.app_info.website_base_path.get_as_string_dangerous()
+ "/reset-password?token="
+ token
+ "&rid="
+ api_options.recipe_id
Expand Down
Loading