Skip to content
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

feat: User creation from dashboard. #128

Merged
merged 30 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
68ed887
feat: API spec for user creation on user dashboard
Chakravarthy7102 Dec 7, 2023
92fdcfa
passwordless user creation api spec
Chakravarthy7102 Dec 7, 2023
92d15ef
add login methods api spec
Chakravarthy7102 Dec 8, 2023
7ab822d
add thirdparty into the response
Chakravarthy7102 Dec 11, 2023
1904fe7
Merge pull request #127 from supertokens/feat/user-creation-apispc
rishabhpoddar Dec 11, 2023
f011c1b
Merge branch 'master' of github.com:supertokens/dashboard into feat/u…
Chakravarthy7102 Dec 20, 2023
425dbbd
feat: add create user dialog component
Chakravarthy7102 Dec 20, 2023
840cb20
Added api sevices and removed redundent api from apispec
Chakravarthy7102 Dec 20, 2023
89df94e
Email password user creation api integration.
Chakravarthy7102 Dec 20, 2023
ac98a7a
progress with passwordless user creation
Chakravarthy7102 Dec 21, 2023
efb8308
feat: passwordless user creation from dashboard
Chakravarthy7102 Dec 21, 2023
f648ac3
fix: phone number component bugs and add inplace search
Chakravarthy7102 Dec 22, 2023
01c215e
bump v0.10.0
Chakravarthy7102 Dec 22, 2023
61f0edf
reset index file
Chakravarthy7102 Dec 22, 2023
cc3ef88
change connection uri
Chakravarthy7102 Dec 22, 2023
90d2f8a
change placeholder value
Chakravarthy7102 Dec 22, 2023
128fe9f
Handle server validation errors
Chakravarthy7102 Dec 24, 2023
6b662e8
remove hardcoded values
Chakravarthy7102 Dec 25, 2023
4ef10ed
fix: changes to frontend according to backend changes
Chakravarthy7102 Dec 25, 2023
078b13f
Remove frontend validations in favor to user defined config validators
Chakravarthy7102 Dec 27, 2023
8b771ec
Improve UX by auto form submissions and refetching user data.
Chakravarthy7102 Dec 27, 2023
f5285d3
fix: input bug that uses multiple instaces of useState.
Chakravarthy7102 Dec 27, 2023
ed8ba36
fix: select compoent overflow issues and copyright changes
Chakravarthy7102 Dec 28, 2023
da9b5b6
fix: change alert messages and handle 400, 500 errors
Chakravarthy7102 Dec 29, 2023
fb7826f
fix: handle feature not enable errors
Chakravarthy7102 Dec 29, 2023
e0e6129
fix: change get-login methods api response
Chakravarthy7102 Dec 29, 2023
3f4d5c1
fix: update frontend code according to backend changes
Chakravarthy7102 Jan 2, 2024
0ff064b
reset index file
Chakravarthy7102 Jan 3, 2024
f2a655d
chore: change copy messages and code structure.
Chakravarthy7102 Jan 3, 2024
c5e1234
fix: added option to stop triggeing the error boundary to useFetchDat…
Chakravarthy7102 Jan 4, 2024
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
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"editor.trimAutoWhitespace": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
"source.organizeImports": "explicit"
},
"files.exclude": {
"**/.DS_Store": true,
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [unreleased]

## [0.10.0] - 2023-12-22

- Added Creating Passwordless and EmailPassword users from the user management dashboard.

## [0.9.1] - 2023-12-19

- Improve UX when showing feature not enabled message for UserRoles recipe.
Expand Down
192 changes: 192 additions & 0 deletions api_spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,10 @@ paths:
properties:
enabled:
type: boolean
contactMethod:
type: string
enum: [PHONE, EMAIL, EMAIL_OR_PHONE]
nullable: true
thirdParty:
type: object
properties:
Expand Down Expand Up @@ -1664,6 +1668,194 @@ paths:
enum:
- Method not supported

/<tenantId>/dashboard/api/user/create/emailpassword:
post:
tags:
- User Creation
summary: Creates a new emailpassword user.
requestBody:
content:
application/json:
schema:
type: object
properties:
email:
type: string
password:
type: string
responses:
200:
description: signup response
content:
application/json:
schema:
oneOf:
- type: object
properties:
status:
type: string
default: "OK"
user:
$ref: "#/components/schemas/authRecipeUser"
recipeUserId:
$ref: "#/components/schemas/userId"
- type: object
properties:
status:
type: string
default: "EMAIL_ALREADY_EXISTS_ERROR"
- type: object
properties:
status:
type: string
default: "FEATURE_NOT_ENABLED_ERROR"

/<tenantId>/dashboard/api/user/create/passwordless:
post:
tags:
- User Creation
summary: Creates a new passwordless user
requestBody:
content:
application/json:
schema:
oneOf:
- type: object
properties:
email:
$ref: "#/components/schemas/email"
example:
email: "[email protected]"
required:
- email
- type: object
properties:
phoneNumber:
$ref: "#/components/schemas/phoneNumber"
required:
- phoneNumber
responses:
200:
description: signup response
content:
application/json:
schema:
oneOf:
- type: object
properties:
status:
type: string
default: "OK"
createdNewRecipeUser:
type: boolean
default: true
user:
$ref: "#/components/schemas/authRecipeUser"
recipeUserId:
$ref: "#/components/schemas/userId"
- type: object
properties:
status:
type: string
default: "FEATURE_NOT_ENABLED_ERROR"
- type: object
properties:
status:
type: string
default: "INPUT_VALIDATION_ERROR"
message:
type: string

components:
schemas:
authRecipeUser:
type: object
properties:
id:
$ref: "#/components/schemas/userId"
isPrimaryUser:
type: boolean
example: true
tenantIds:
type: array
items:
$ref: "#/components/schemas/tenantId"
timeJoined:
$ref: "#/components/schemas/timeJoined"
emails:
type: array
items:
$ref: "#/components/schemas/email"
phoneNumbers:
type: array
items:
$ref: "#/components/schemas/phoneNumber"
thirdParty:
type: array
items:
type: object
properties:
id:
$ref: "#/components/schemas/thirdPartyId"
userId:
$ref: "#/components/schemas/thirdPartyUserId"
loginMethods:
type: array
items:
type: object
properties:
tenantIds:
type: array
items:
$ref: "#/components/schemas/tenantId"
recipeUserId:
$ref: "#/components/schemas/userId"
verified:
type: boolean
example: true
timeJoined:
$ref: "#/components/schemas/timeJoined"
recipeId:
$ref: "#/components/schemas/recipeId"
email:
$ref: "#/components/schemas/email"
phoneNumber:
$ref: "#/components/schemas/phoneNumber"
thirdParty:
type: object
properties:
id:
$ref: "#/components/schemas/thirdPartyId"
userId:
$ref: "#/components/schemas/thirdPartyUserId"
recipeId:
type: string
enum:
- emailpassword
- passwordless
- thirdparty
thirdPartyId:
type: string
example: google
thirdPartyUserId:
type: string
example: 106347997792363865062
email:
type: string
example: [email protected]
userId:
type: string
example: fa7a0841-b533-4478-95533-0fde890c3483
timeJoined:
type: number
example: 1623918032231
phoneNumber:
type: string
example: "+14155552671"
tenantId:
type: string
example: "customer1"

servers:
# Added by API Auto Mocking Plugin
- description: SwaggerHub API Auto Mocking
Expand Down
4 changes: 2 additions & 2 deletions build/static/css/main.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/static/css/main.css.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/static/js/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/static/js/bundle.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dashboard",
"version": "0.9.1",
"version": "0.10.0",
"private": true,
"dependencies": {
"@babel/core": "^7.16.0",
Expand Down
3 changes: 3 additions & 0 deletions src/api/tenants/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@

import { getApiUrl, useFetchData } from "../../utils";

export type PasswordlessContactMethod = "PHONE" | "EMAIL" | "EMAIL_OR_PHONE";

export type Tenant = {
tenantId: string;
emailPassword: {
enabled: boolean;
};
passwordless: {
enabled: boolean;
contactMethod?: PasswordlessContactMethod;
};
thirdParty: {
enabled: boolean;
Expand Down
89 changes: 89 additions & 0 deletions src/api/user/create/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { User } from "../../../ui/pages/usersList/types";
import { getApiUrl, useFetchData } from "../../../utils";

export type CreatePasswordlessUserPayload = {
email?: string;
phoneNumber?: string;
};

rishabhpoddar marked this conversation as resolved.
Show resolved Hide resolved
interface ICreateUserService {
createEmailPasswordUser: (
tenantId: string,
email: string,
password: string
) => Promise<CreateEmailPasswordUserResponse>;
createPasswordlessUser: (
tenantId: string,
data: CreatePasswordlessUserPayload
) => Promise<CreatePasswordlessUserResponse>;
}

type CreateEmailPasswordUserResponse =
| {
status: "OK";
user: User;
recipeUserId: string;
}
| {
status: "EMAIL_ALREADY_EXISTS_ERROR" | "FEATURE_NOT_ENABLED_ERROR";
};

type CreatePasswordlessUserResponse =
| {
status: "OK";
createdNewRecipeUser: boolean;
user: User;
recipeUserId: string;
}
| {
status: "FEATURE_NOT_ENABLED_ERROR";
}
| {
status: "INPUT_VALIDATION_ERROR";
message: string;
};

const useCreateUserService = (): ICreateUserService => {
const fetchData = useFetchData();

const createEmailPasswordUser = async (
tenantId: string | undefined,
email: string,
password: string
): Promise<CreateEmailPasswordUserResponse> => {
const response = await fetchData({
url: getApiUrl("/api/user/create/emailpassword", tenantId),
method: "POST",
config: {
body: JSON.stringify({
email,
password,
}),
},
});
return await response.json();
};

const createPasswordlessUser = async (
tenantId: string,
data: {
email?: string;
phoneNumber?: string;
}
): Promise<CreatePasswordlessUserResponse> => {
const response = await fetchData({
url: getApiUrl("/api/user/create/passwordless", tenantId),
method: "POST",
config: {
body: JSON.stringify({
...data,
}),
},
});
return await response.json();
};

return { createEmailPasswordUser, createPasswordlessUser };
};

export default useCreateUserService;
24 changes: 24 additions & 0 deletions src/ui/components/alert/alert.scss
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,30 @@
}
}

&.secondary {
border-radius: 6px;
border: 1px solid #0062e1;
background: rgba(0, 98, 225, 0.05);

& > span {
background: #0062e1;
color: #fff;
}

& > div {
color: #104993;
}

a {
color: #007aff;
font-weight: 500;
}
}

&.sm {
padding: 20px 14px;
}

a:hover {
background: transparent !important;
}
Expand Down
Loading
Loading