Skip to content

Commit ef02e0f

Browse files
Merge pull request #293 from supertokens/email-password-feature-branch
feat: Email password feature branch
2 parents f2f3253 + 58a8eca commit ef02e0f

File tree

23 files changed

+250
-78
lines changed

23 files changed

+250
-78
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## unreleased
99

10+
## [0.12.3] - 2023-02-27
11+
- Adds APIs and logic to the dashboard recipe to enable email password based login
1012
## [0.12.2] - 2023-02-23
1113
- Fix expiry time of access token cookie.
1214

coreDriverInterfaceSupported.json

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
{
2-
"_comment": "contains a list of core-driver interfaces branch names that this core supports",
3-
"versions": [
4-
"2.9",
5-
"2.10",
6-
"2.11",
7-
"2.12",
8-
"2.13",
9-
"2.14",
10-
"2.15"
11-
]
12-
}
2+
"_comment": "contains a list of core-driver interfaces branch names that this core supports",
3+
"versions": [
4+
"2.9",
5+
"2.10",
6+
"2.11",
7+
"2.12",
8+
"2.13",
9+
"2.14",
10+
"2.15",
11+
"2.16",
12+
"2.17",
13+
"2.18"
14+
]
15+
}

examples/with-flask/with-thirdpartyemailpassword/app.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from dotenv import load_dotenv
44
from flask import Flask, abort, g, jsonify
55
from flask_cors import CORS
6+
67
from supertokens_python import (
78
InputAppInfo,
89
SupertokensConfig,
@@ -11,9 +12,9 @@
1112
)
1213
from supertokens_python.framework.flask import Middleware
1314
from supertokens_python.recipe import (
15+
emailverification,
1416
session,
1517
thirdpartyemailpassword,
16-
emailverification,
1718
)
1819
from supertokens_python.recipe.session.framework.flask import verify_session
1920
from supertokens_python.recipe.thirdpartyemailpassword import (

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070

7171
setup(
7272
name="supertokens_python",
73-
version="0.12.2",
73+
version="0.12.3",
7474
author="SuperTokens",
7575
license="Apache 2.0",
7676
author_email="[email protected]",

supertokens_python/constants.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,19 @@
1111
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1212
# License for the specific language governing permissions and limitations
1313
# under the License.
14-
SUPPORTED_CDI_VERSIONS = ["2.9", "2.10", "2.11", "2.12", "2.13", "2.14", "2.15"]
15-
VERSION = "0.12.2"
14+
SUPPORTED_CDI_VERSIONS = [
15+
"2.9",
16+
"2.10",
17+
"2.11",
18+
"2.12",
19+
"2.13",
20+
"2.14",
21+
"2.15",
22+
"2.16",
23+
"2.17",
24+
"2.18",
25+
]
26+
VERSION = "0.12.3"
1627
TELEMETRY = "/telemetry"
1728
USER_COUNT = "/users/count"
1829
USER_DELETE = "/user/remove"
@@ -25,4 +36,4 @@
2536
FDI_KEY_HEADER = "fdi-version"
2637
API_VERSION = "/apiversion"
2738
API_VERSION_HEADER = "cdi-version"
28-
DASHBOARD_VERSION = "0.3"
39+
DASHBOARD_VERSION = "0.4"

supertokens_python/querier.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,18 @@ async def f(url: str) -> Response:
166166

167167
return await self.__send_request_helper(path, "POST", f, len(self.__hosts))
168168

169-
async def send_delete_request(self, path: NormalisedURLPath):
169+
async def send_delete_request(
170+
self, path: NormalisedURLPath, params: Union[Dict[str, Any], None] = None
171+
):
172+
if params is None:
173+
params = {}
174+
170175
async def f(url: str) -> Response:
171176
async with AsyncClient() as client:
172177
return await client.delete( # type:ignore
173-
url, headers=await self.__get_headers_with_api_version(path)
178+
url,
179+
params=params,
180+
headers=await self.__get_headers_with_api_version(path),
174181
)
175182

176183
return await self.__send_request_helper(path, "DELETE", f, len(self.__hosts))

supertokens_python/recipe/dashboard/__init__.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,17 @@
1414

1515
from __future__ import annotations
1616

17-
from typing import Optional, Callable
17+
from typing import TYPE_CHECKING, Callable, Optional, Union
1818

19-
from supertokens_python import AppInfo, RecipeModule
20-
from supertokens_python.recipe.dashboard.utils import InputOverrideConfig
19+
if TYPE_CHECKING:
20+
from supertokens_python import AppInfo, RecipeModule
21+
from supertokens_python.recipe.dashboard.utils import InputOverrideConfig
2122

2223
from .recipe import DashboardRecipe
2324

2425

2526
def init(
26-
api_key: str,
27+
api_key: Union[str, None] = None,
2728
override: Optional[InputOverrideConfig] = None,
2829
) -> Callable[[AppInfo], RecipeModule]:
2930
return DashboardRecipe.init(

supertokens_python/recipe/dashboard/api/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
# under the License.
1414
from .api_key_protector import api_key_protector
1515
from .dashboard import handle_dashboard_api
16+
from .signin import handle_emailpassword_signin_api
17+
from .signout import handle_emailpassword_signout_api
1618
from .userdetails.user_delete import handle_user_delete
1719
from .userdetails.user_email_verify_get import handle_user_email_verify_get
1820
from .userdetails.user_email_verify_put import handle_user_email_verify_put
@@ -45,4 +47,6 @@
4547
"handle_user_sessions_post",
4648
"handle_user_password_put",
4749
"handle_email_verify_token_post",
50+
"handle_emailpassword_signin_api",
51+
"handle_emailpassword_signout_api",
4852
]

supertokens_python/recipe/dashboard/api/implementation.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@
1717
from textwrap import dedent
1818
from typing import TYPE_CHECKING, Any, Dict
1919

20-
from supertokens_python.normalised_url_domain import NormalisedURLDomain
2120
from supertokens_python import Supertokens
21+
from supertokens_python.normalised_url_domain import NormalisedURLDomain
2222
from supertokens_python.normalised_url_path import NormalisedURLPath
23+
2324
from ..constants import DASHBOARD_API
24-
from ..interfaces import (
25-
APIInterface,
26-
)
25+
from ..interfaces import APIInterface
2726

2827
if TYPE_CHECKING:
2928
from ..interfaces import APIOptions
@@ -48,7 +47,7 @@ async def dashboard_get(
4847

4948
connection_uri = ""
5049
super_tokens_instance = Supertokens.get_instance()
51-
50+
auth_mode = options.config.auth_mode
5251
connection_uri = super_tokens_instance.supertokens_config.connection_uri
5352

5453
dashboard_path = options.app_info.api_base_path.append(
@@ -65,6 +64,7 @@ async def dashboard_get(
6564
window.staticBasePath = "${bundleDomain}/static"
6665
window.dashboardAppPath = "${dashboardPath}"
6766
window.connectionURI = "${connectionURI}"
67+
window.authMode = "${authMode}"
6868
</script>
6969
<script defer src="${bundleDomain}/static/js/bundle.js"></script></head>
7070
<link href="${bundleDomain}/static/css/main.css" rel="stylesheet" type="text/css">
@@ -81,6 +81,7 @@ async def dashboard_get(
8181
bundleDomain=bundle_domain,
8282
dashboardPath=dashboard_path,
8383
connectionURI=connection_uri,
84+
authMode=auth_mode,
8485
)
8586

8687
self.dashboard_get = dashboard_get
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
2+
#
3+
# This software is licensed under the Apache License, Version 2.0 (the
4+
# "License") as published by the Apache Software Foundation.
5+
#
6+
# You may not use this file except in compliance with the License. You may
7+
# obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
from __future__ import annotations
15+
16+
from typing import TYPE_CHECKING
17+
18+
if TYPE_CHECKING:
19+
from supertokens_python.recipe.dashboard.interfaces import APIInterface, APIOptions
20+
21+
from supertokens_python.exceptions import raise_bad_input_exception
22+
from supertokens_python.normalised_url_path import NormalisedURLPath
23+
from supertokens_python.querier import Querier
24+
from supertokens_python.utils import send_200_response
25+
26+
27+
async def handle_emailpassword_signin_api(_: APIInterface, api_options: APIOptions):
28+
body = await api_options.request.json()
29+
if body is None:
30+
raise_bad_input_exception("Please send body")
31+
email = body.get("email")
32+
password = body.get("password")
33+
34+
if email is None or not isinstance(email, str):
35+
raise_bad_input_exception("Missing required parameter 'email'")
36+
if password is None or not isinstance(password, str):
37+
raise_bad_input_exception("Missing required parameter 'password'")
38+
response = await Querier.get_instance().send_post_request(
39+
NormalisedURLPath("/recipe/dashboard/signin"),
40+
{"email": email, "password": password},
41+
)
42+
43+
if "status" in response and response["status"] == "OK":
44+
return send_200_response(
45+
{"status": "OK", "sessionId": response["sessionId"]}, api_options.response
46+
)
47+
if "status" in response and response["status"] == "INVALID_CREDENTIALS_ERROR":
48+
return send_200_response(
49+
{"status": "INVALID_CREDENTIALS_ERROR"},
50+
api_options.response,
51+
)
52+
if "status" in response and response["status"] == "USER_SUSPENDED_ERROR":
53+
return send_200_response(
54+
{"status": "USER_SUSPENDED_ERROR", "message": response["message"]},
55+
api_options.response,
56+
)

0 commit comments

Comments
 (0)