Skip to content

Commit 9e013e9

Browse files
committed
chores: Update CHANGELOG
1 parent 0c0b0ce commit 9e013e9

File tree

1 file changed

+361
-4
lines changed

1 file changed

+361
-4
lines changed

CHANGELOG.md

Lines changed: 361 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,366 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Breaking changes
1111

12+
- Added support for CDI version `2.21`
13+
<!-- FIXME -->
14+
- Dropped support for CDI version `2.8` - `2.18`
15+
- Changed the interface and configuration of the Session recipe, see below for details. If you do not use the Session recipe directly and do not provide custom configuration, then no migration is necessary.
16+
- `get_access_token_payload` will now return standard (`sub`, `iat`, `exp`) claims and some SuperTokens specific claims along the user defined ones in `get_access_token_payload`.
17+
- Some claim names are now prohibited in the root level of the access token payload:
18+
- They are: `sub`, `iat`, `exp`, `sessionHandle`, `parentRefreshTokenHash1`, `refreshTokenHash1`, `antiCsrfToken`
19+
- If you used these in the root level of the access token payload, then you'll need to migrate your sessions or they will be logged out during the next refresh
20+
- These props should be renamed (e.g., by adding a prefix) or moved inside an object in the access token payload
21+
- You can migrate these sessions by updating their payload to match your new structure, by calling `merge_into_access_token_payload`
22+
- New access tokens are valid JWTs now
23+
- They can be used directly (i.e.: by calling `get_access_token` on the session) if you need a JWT
24+
- The `jwt` prop in the access token payload is removed
25+
- Changed the Session recipe interface - `create_new_session`, `get_session` and `refresh_session` overrides now do not take response and request and return status instead of throwing
26+
27+
### Configuration changes
28+
29+
- Added `use_dynamic_access_token_signing_key` (defaults to `True`) option to the Session recipe config
30+
- Added `expose_access_token_to_frontend_in_cookie_based_auth` (defaults to `False`) option to the Session recipe config
31+
- JWT and OpenId related configuration has been removed from the Session recipe config. If necessary, they can be added by initializing the OpenId recipe before the Session recipe.
32+
33+
34+
### Interface changes
35+
1236
- Renamed `get_session_data` to `get_session_data_from_database` to clarity that it always hits the DB
1337
- Renamed `update_session_data` to `update_session_data_in_database`
1438
- Renamed `session_data` to `session_data_in_database` in `SessionInformation` and the input to `create_new_session`
39+
- Added new `check_database` param to `verify_session` and `get_session`
40+
- Removed `status` from `jwks_get` output (function & API)
41+
- Added new optional `use_static_signing_key` param to `createJWT`
42+
- Removed deprecated `update_access_token_payload` and `regenerate_access_token` from the Session recipe interface
43+
- Removed `get_access_token_lifetime_ms` and `get_refresh_token_lifetime_ms` functions
44+
45+
46+
## Changes
47+
48+
- The Session recipe now always initializes the OpenID recipe if it hasn't been initialized.
49+
- Refactored how access token validation is done
50+
- Removed the handshake call to improve start-up times
51+
- Added support for new access token version
52+
53+
### Added
54+
55+
- Added `create_new_session_without_request_response`, `get_session_without_request_response`, `refresh_session_without_request_response` to the Session recipe.
56+
- Added `get_all_session_tokens_dangerously` to session objects (`SessionContainer`)
57+
- Added `attach_to_request_response` to session objects (`SessionContainer`)
58+
59+
### Migration
60+
61+
#### If self-hosting core
62+
63+
1. You need to update the core version
64+
2. There are manual migration steps needed. Check out the core changelogs for more details.
65+
66+
#### If you used the jwt feature of the session recipe
67+
68+
1. Add `expose_access_token_to_frontend_in_cookie_based_auth=true` to the Session recipe config on the backend if you need to access the JWT on the frontend.
69+
2. On the frontend where you accessed the JWT before by: `(await Session.getAccessTokenPayloadSecurely()).jwt` update to:
70+
71+
```tsx
72+
let jwt = null;
73+
const accessTokenPayload = await Session.getAccessTokenPayloadSecurely();
74+
if (accessTokenPayload.jwt === undefined) {
75+
jwt = await Session.getAccessToken();
76+
} else {
77+
// This branch is only required if there are valid access tokens created before the update
78+
// It can be removed after the validity period ends
79+
jwt = accessTokenPayload.jwt;
80+
}
81+
```
82+
83+
3. On the backend if you accessed the JWT before by `session.get_access_token_payload()['jwt']` please update to:
84+
85+
```python
86+
jwt = None
87+
access_token_payload = await session.get_access_token_payload_securely() # FIXME
88+
if accessTokenPayload.get('jwt') is None:
89+
jwt = await session.get_access_token()
90+
else:
91+
# This branch is only required if there are valid access tokens created before the update
92+
# It can be removed after the validity period ends
93+
jwt = accessTokenPayload.jwt
94+
```
95+
96+
#### If you used to set an issuer in the session recipe `jwt` configuration
97+
98+
- You can add an issuer claim to access tokens by overriding the `create_new_session` function in the session recipe init.
99+
- Check out https://supertokens.com/docs/passwordless/common-customizations/sessions/claims/access-token-payload#during-session-creation for more information
100+
- You can add an issuer claim to JWTs created by the JWT recipe by passing the `iss` claim as part of the payload.
101+
- You can set the OpenId discovery configuration as follows:
102+
103+
Before:
104+
105+
```tsx
106+
import SuperTokens from "supertokens-auth-react";
107+
import Session from "supertokens-auth-react/recipe/session";
108+
109+
SuperTokens.init({
110+
appInfo: {
111+
apiDomain: "...",
112+
appName: "...",
113+
websiteDomain: "...",
114+
},
115+
recipeList: [
116+
Session.init({
117+
jwt: {
118+
enable: true,
119+
issuer: "...",
120+
},
121+
}),
122+
],
123+
});
124+
```
125+
126+
After:
127+
128+
```tsx
129+
import SuperTokens from "supertokens-auth-react";
130+
import Session from "supertokens-auth-react/recipe/session";
131+
132+
SuperTokens.init({
133+
appInfo: {
134+
apiDomain: "...",
135+
appName: "...",
136+
websiteDomain: "...",
137+
},
138+
recipeList: [
139+
Session.init({
140+
getTokenTransferMethod: () => "header",
141+
override: {
142+
openIdFeature: {
143+
functions: originalImplementation => ({
144+
...originalImplementation,
145+
getOpenIdDiscoveryConfiguration: async (input) => ({
146+
issuer: "your issuer",
147+
jwks_uri: "https://your.api.domain/auth/jwt/jwks.json",
148+
status: "OK"
149+
}),
150+
})
151+
}
152+
}
153+
});
154+
],
155+
});
156+
```
157+
158+
#### If you used `session_data` (not `access_token_payload`)
159+
160+
Related functions/prop names have changes (`session_data` became `session_data_from_database`):
161+
162+
- Renamed `get_session_data` to `get_session_data_from_database` to clarify that it always hits the DB
163+
- Renamed `update_session_data` to `update_session_data_in_database`
164+
- Renamed `session_data` to `session_data_in_database` in `SessionInformationResult` and the input to `create_new_session`
165+
166+
#### If you used to set `access_token_blacklisting` in the core config
167+
168+
- You should now set `check_database` to true in the `verify_session` params.
169+
170+
#### If you used to set `access_token_signing_key_dynamic` in the core config
171+
172+
- You should now set `use_dynamic_access_token_signing_key` in the Session recipe config.
173+
174+
#### If you used to use standard/protected props in the access token payload root:
175+
176+
1. Update you application logic to rename those props (e.g., by adding a prefix)
177+
2. Update the session recipe config (in this example `sub` is the protected property we are updating by adding the `app` prefix):
178+
179+
Before:
180+
181+
```python
182+
from typing import Any, Dict, Optional
183+
from supertokens_python.recipe.session.interfaces import RecipeInterface as SessionRecipeInterface
184+
from supertokens_python.recipe import session
185+
186+
async def override_session_functions(oi: SessionRecipeInterface):
187+
oi_create_new_session = oi.create_new_session
188+
189+
async def create_new_session(
190+
user_id: str,
191+
access_token_payload: Optional[Dict[str, Any]],
192+
session_data_in_database: Optional[Dict[str, Any]],
193+
disable_anti_csrf: Optional[bool],
194+
user_context: Dict[str, Any],
195+
):
196+
return oi_create_new_session(
197+
user_id,
198+
{**access_token_payload, "sub": access_token_payload["userId"] + "!!!" }
199+
session_data_in_database,
200+
disable_anti_csrf,
201+
user_context,
202+
)
203+
204+
oi.create_new_session = create_new_session
205+
206+
session.init(
207+
override=session.InputOverrideConfig(functions=override_session_functions)
208+
)
209+
```
210+
211+
After:
212+
213+
```python
214+
from typing import Any, Dict, Optional
215+
from supertokens_python.recipe.session.interfaces import RecipeInterface as SessionRecipeInterface
216+
from supertokens_python.recipe import session
217+
218+
async def override_session_functions(oi: SessionRecipeInterface):
219+
oi_get_session = oi.get_session
220+
oi_create_new_session = oi.create_new_session
221+
222+
async def get_session(
223+
access_token: str,
224+
anti_csrf_token: Optional[str],
225+
anti_csrf_check: Optional[bool] = None,
226+
check_database: Optional[bool] = None,
227+
override_global_claim_validators: Optional[
228+
Callable[
229+
[List[SessionClaimValidator], SessionContainer, Dict[str, Any]],
230+
MaybeAwaitable[List[SessionClaimValidator]],
231+
]
232+
] = None,
233+
user_context: Optional[Dict[str, Any]] = None,
234+
):
235+
result = oi_get_session(input)
236+
if result:
237+
orig_payload = result.get_access_token_payload()
238+
if orig_payload["appSub"] is None:
239+
await result.merge_into_access_token_payload({"appSub": orig_payload["sub"], "sub": None})
240+
241+
return result
242+
243+
async def create_new_session(
244+
user_id: str,
245+
access_token_payload: Optional[Dict[str, Any]],
246+
session_data_in_database: Optional[Dict[str, Any]],
247+
disable_anti_csrf: Optional[bool],
248+
user_context: Dict[str, Any],
249+
):
250+
return oi_create_new_session(
251+
user_id,
252+
{**access_token_payload, "appSub": access_token_payload["userId"] + "!!!" }
253+
session_data_in_database,
254+
disable_anti_csrf,
255+
user_context
256+
)
257+
258+
oi.get_session = get_session
259+
oi.create_new_session = create_new_session
260+
261+
session.init(
262+
override=session.InputOverrideConfig(
263+
functions=override_session_functions,
264+
)
265+
)
266+
```
267+
268+
#### If you added an override for `create_new_session`/`refresh_session`/`get_session`:
269+
270+
This example uses `get_session`, but the changes required for the other ones are very similar. Before:
271+
272+
```python
273+
from typing import Any, Dict, Optional
274+
from supertokens_python.recipe.session.interfaces import RecipeInterface as SessionRecipeInterface
275+
from supertokens_python.recipe import session
276+
277+
278+
async def override_session_functions():
279+
oi.get_session = oi.get_session
280+
281+
async def get_session(
282+
request: Any,
283+
access_token: str,
284+
anti_csrf_token: Optional[str],
285+
anti_csrf_check: Optional[bool] = None,
286+
check_database: Optional[bool] = None,
287+
override_global_claim_validators: Optional[
288+
Callable[
289+
[List[SessionClaimValidator], SessionContainer, Dict[str, Any]],
290+
MaybeAwaitable[List[SessionClaimValidator]],
291+
]
292+
] = None,
293+
user_context: Optional[Dict[str, Any]] = None,
294+
):
295+
print(request)
296+
try:
297+
_session = await oi_get_session(
298+
request,
299+
access_token,
300+
anti_csrf_token,
301+
anti_csrf_check,
302+
check_database,
303+
override_global_claim_validators,
304+
user_context,
305+
)
306+
print(_session)
307+
return _session
308+
except Exception as e:
309+
print(e)
310+
raise e
311+
312+
session.init(
313+
override=session.InputOverrideConfig(
314+
functions=override_session_functions,
315+
)
316+
)
317+
```
318+
319+
After:
320+
321+
```python
322+
from typing import Any, Dict, Optional
323+
from supertokens_python.recipe.session.interfaces import RecipeInterface as SessionRecipeInterface
324+
from supertokens_python.recipe import session
325+
326+
async def override_session_functions():
327+
oi.get_session = oi.get_session
328+
329+
async def get_session(
330+
access_token: str,
331+
anti_csrf_token: Optional[str],
332+
anti_csrf_check: Optional[bool] = None,
333+
check_database: Optional[bool] = None,
334+
override_global_claim_validators: Optional[
335+
Callable[
336+
[List[SessionClaimValidator], SessionContainer, Dict[str, Any]],
337+
MaybeAwaitable[List[SessionClaimValidator]],
338+
]
339+
] = None,
340+
user_context: Optional[Dict[str, Any]] = None,
341+
):
342+
request = user_context["_default"]["request"]
343+
print(request)
344+
345+
session_res = await oi_get_session(
346+
request,
347+
access_token,
348+
anti_csrf_token,
349+
anti_csrf_check,
350+
check_database,
351+
override_global_claim_validators,
352+
user_context,
353+
)
354+
if session_res.status == "OK":
355+
print(session_res.session)
356+
else:
357+
print(session_res.status)
358+
print(session_res.error)
359+
360+
return session_res
361+
362+
363+
session.init(
364+
override=session.InputOverrideConfig(
365+
functions=override_session_functions,
366+
)
367+
)
368+
```
369+
370+
371+
15372

16373

17374
## [0.12.4] - 2023-03-29
@@ -253,7 +610,7 @@ init(
253610
def verify_email_for_passwordless_users():
254611
pagination_token = None
255612
done = False
256-
613+
257614
while not done:
258615
res = get_users_newest_first(
259616
limit=100,
@@ -266,7 +623,7 @@ def verify_email_for_passwordless_users():
266623
token_res = create_email_verification_token(user.user_id, user.email)
267624
if isinstance(token_res, CreateEmailVerificationTokenOkResult):
268625
verify_email_using_token(token_res.token)
269-
626+
270627
done = res.next_pagination_token is None
271628
if not done:
272629
pagination_token = res.next_pagination_token
@@ -296,7 +653,7 @@ The `UserRoles` recipe now adds role and permission information into the access
296653

297654
## [0.10.2] - 2022-07-14
298655
### Bug fix
299-
- Make `user_context` optional in userroles recipe syncio functions.
656+
- Make `user_context` optional in userroles recipe syncio functions.
300657

301658
## [0.10.1] - 2022-07-11
302659

@@ -831,4 +1188,4 @@ init(
8311188
- Middleware, error handlers and verify session for each framework.
8321189
- Created a wrapper for async to sync for supporting older version of python web frameworks.
8331190
- Base tests for each framework.
834-
- New requirements in the setup file.
1191+
- New requirements in the setup file.

0 commit comments

Comments
 (0)