Skip to content

Commit ae6fca5

Browse files
authored
Merge pull request #1040 from supertokens/feat/profile-details-plugin
Feat/profile details plugin
2 parents a2d88d6 + e06a8bd commit ae6fca5

File tree

14 files changed

+1948
-25
lines changed

14 files changed

+1948
-25
lines changed

docs/additional-verification/captcha.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ SuperTokens.init({
105105
});
106106
```
107107

108+
:::info no-title
109+
If you are using a captcha input that renders an input on the frontend, you will have to [disable the use of shadow DOM](/docs/references/frontend-sdks/prebuilt-ui/shadow-dom) when you initialize the SDK.
110+
:::
111+
108112
### 3. Customize the plugin
109113

110114
By default, the plugin performs CAPTCHA validation on the following authentication flows:
Lines changed: 352 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
1+
---
2+
title: Profile Management
3+
hide_title: true
4+
sidebar_position: 4
5+
description: Add comprehensive user profile management with customizable form fields and account information display using the profile details plugin
6+
page_type: tutorial
7+
---
8+
9+
# User profile management
10+
11+
## Overview
12+
13+
This tutorial shows you how to add comprehensive user profile management to your **SuperTokens** authentication flows.
14+
The guide makes use of the `plugins` functionality which provides a complete profile management interface with customizable form fields, account information display, and automatic third-party data integration.
15+
16+
The functionality integrates with the [progressive profiling plugin](/docs/post-authentication/user-management/progressive-profiling) by default.
17+
This allows you to:
18+
- Gradually collect user information through the progressive profiling flow
19+
- Display collected information in the profile details interface
20+
- Keep both systems synchronized automatically
21+
22+
## Before you start
23+
24+
The profile details plugin supports only the `React` and `NodeJS` SDKs.
25+
Support for other platforms is under active development.
26+
27+
You need to start from a working **SuperTokens** setup with the profile base plugin already configured.
28+
If you haven't done that already, please refer to the [Quickstart Guides](/docs/quickstart/introduction).
29+
30+
## Steps
31+
32+
### 1. Initialize the backend plugin
33+
34+
#### 1.1 Install the plugin
35+
36+
```bash
37+
npm install @supertokens-plugins/profile-details-nodejs
38+
```
39+
40+
#### 1.2 Update your backend SDK configuration
41+
42+
The backend plugin exposes new endpoints which, in turn, get used by the frontend implementation.
43+
44+
```typescript
45+
import SuperTokens from "supertokens-node";
46+
import ProfileDetailsPlugin from "@supertokens-plugins/profile-details-nodejs";
47+
48+
SuperTokens.init({
49+
appInfo: {
50+
// your app info
51+
},
52+
recipeList: [
53+
// your recipes (Session recipe is required)
54+
],
55+
experimental: {
56+
plugins: [
57+
ProfileDetailsPlugin.init({
58+
sections: [
59+
{
60+
id: "personal-details",
61+
label: "Personal Information",
62+
description: "Your personal details",
63+
fields: [
64+
{
65+
id: "firstName",
66+
label: "First Name",
67+
type: "string",
68+
required: true,
69+
placeholder: "Enter your first name",
70+
},
71+
{
72+
id: "lastName",
73+
label: "Last Name",
74+
type: "string",
75+
required: true,
76+
placeholder: "Enter your last name",
77+
},
78+
{
79+
id: "company",
80+
label: "Company",
81+
type: "string",
82+
required: false,
83+
placeholder: "Enter your company name",
84+
},
85+
],
86+
},
87+
{
88+
id: "preferences",
89+
label: "Preferences",
90+
description: "Customize your experience",
91+
fields: [
92+
{
93+
id: "avatar",
94+
label: "Profile Picture",
95+
type: "image-url",
96+
required: false,
97+
placeholder: "https://example.com/avatar.jpg",
98+
},
99+
{
100+
id: "theme",
101+
label: "Preferred Theme",
102+
type: "select",
103+
required: false,
104+
options: [
105+
{ value: "light", label: "Light" },
106+
{ value: "dark", label: "Dark" },
107+
{ value: "auto", label: "Auto" },
108+
],
109+
defaultValue: "auto",
110+
},
111+
],
112+
},
113+
],
114+
registerSectionsForProgressiveProfiling: true, // Optional: defaults to true
115+
}),
116+
],
117+
},
118+
});
119+
```
120+
121+
##### Supported field types
122+
123+
The plugin supports the following field types:
124+
125+
| Field Type | Description | Value Type | Example Use Case |
126+
|------------|-------------|------------|------------------|
127+
| `string` | Single-line text input | `string` | Name, title, company |
128+
| `text` | Multi-line text area | `string` | Bio, description, comments |
129+
| `number` | Numeric input | `number` | Age, salary, experience |
130+
| `boolean` | Checkbox input | `boolean` | Newsletter subscription |
131+
| `toggle` | Toggle switch | `boolean` | Feature preferences |
132+
| `email` | Email input with validation | `string` | Contact email |
133+
| `phone` | Phone number input | `string` | Contact number |
134+
| `date` | Date picker | `string` (ISO 8601 format) | Birth date, start date |
135+
| `select` | Dropdown selection | `string` | Country, department, role |
136+
| `multiselect` | Multiple selection dropdown | `string[]` | Skills, interests, languages |
137+
| `password` | Password input | `string` | API keys, secure tokens |
138+
| `url` | URL input with validation | `string` | Website, social profiles |
139+
| `image-url` | Image URL input with preview | `string` | Profile picture, logo |
140+
141+
##### Third-party data integration
142+
143+
The plugin automatically integrates with third-party authentication providers to populate profile fields.
144+
When users sign in using external providers, the plugin maps provider data to profile fields (if the fields are configured):
145+
- `firstName`: Maps from `name`, `given_name`, or `first_name`
146+
- `lastName`: Maps from `family_name` or `last_name`
147+
- `avatar`: Maps from `picture` or `avatar_url`
148+
149+
:::info no-title
150+
You can customize how third-party data maps to your profile fields by overriding the function `getFieldValueFromThirdPartyUserInfo`.
151+
152+
```typescript
153+
import ProfileDetailsPlugin from "@supertokens-plugins/profile-details-node";
154+
155+
SuperTokens.init({
156+
// ... other config
157+
experimental: {
158+
plugins: [
159+
ProfileDetailsPlugin.init({
160+
override: (oI) => ({
161+
...oI,
162+
getFieldValueFromThirdPartyUserInfo: (providerId, field, rawUserInfoFromProvider, profile) => {
163+
return rawUserInfoFromProvider[field.id];
164+
},
165+
}),
166+
}),
167+
],
168+
},
169+
});
170+
```
171+
:::
172+
173+
### 2. Initialize the frontend plugin
174+
175+
#### 2.1 Install the plugin
176+
177+
```bash
178+
npm install @supertokens-plugins/profile-details-react
179+
```
180+
181+
#### 2.2 Update your frontend SDK configuration
182+
183+
Initialize the frontend plugin in your existing configuration.
184+
With the following setup the `/user/profile` path renders the profile details page.
185+
186+
```typescript
187+
import SuperTokens from "supertokens-auth-react";
188+
import ProfileDetailsPlugin from "@supertokens-plugins/profile-details-react";
189+
190+
SuperTokens.init({
191+
appInfo: {
192+
// your app info
193+
},
194+
recipeList: [
195+
// your recipes
196+
],
197+
experimental: {
198+
plugins: [
199+
ProfileDetailsPlugin.init(),
200+
],
201+
},
202+
});
203+
```
204+
205+
:::info
206+
The user profile page gets rendered by default on the `/user/profile` path.
207+
If you want to change the path, you have to initialize the `profile-base-react` plugin with the `profilePagePath` option.
208+
209+
```typescript
210+
import SuperTokens from "supertokens-auth-react";
211+
import ProfileBasePlugin from "@supertokens-plugins/profile-base-react";
212+
import ProfileDetailsPlugin from "@supertokens-plugins/profile-details-react";
213+
214+
SuperTokens.init({
215+
appInfo: {
216+
// your app info
217+
},
218+
recipeList: [
219+
// your recipes
220+
],
221+
experimental: {
222+
plugins: [
223+
ProfileBasePlugin.init({
224+
profilePagePath: "/user/profile",
225+
}),
226+
ProfileDetailsPlugin.init(),
227+
],
228+
},
229+
});
230+
```
231+
:::
232+
233+
### 3. Test the implementation
234+
235+
Authenticate and then visit the `/user/profile` path.
236+
You should see the new interface that renders the profile data.
237+
238+
<img
239+
alt="Progressive profiling setup interface"
240+
width="700px"
241+
src="/img/user-profile.png"
242+
/>
243+
244+
## Customization
245+
246+
### Custom field components
247+
248+
To add custom rendering behavior for fields you have to pass an override during plugin initialization.
249+
250+
```typescript
251+
import ProfileDetailsPlugin from "@supertokens-plugins/profile-details-react";
252+
import { CustomStringInput, CustomStringView } from "./your-custom-components";
253+
254+
SuperTokens.init({
255+
// ... other config
256+
experimental: {
257+
plugins: [
258+
ProfileDetailsPlugin.init({
259+
override: (oI) => ({
260+
...oI,
261+
fieldInputComponentMap: (originalMap) => ({
262+
...originalMap,
263+
string: CustomStringInput,
264+
}),
265+
fieldViewComponentMap: (originalMap) => ({
266+
...originalMap,
267+
string: CustomStringView,
268+
}),
269+
}),
270+
}),
271+
],
272+
},
273+
});
274+
```
275+
276+
### Custom user interface
277+
278+
To create your own UI you can use the `usePluginContext` hook.
279+
It exposes an interface which you can use to call the endpoints exposed by the backend plugin.
280+
281+
```typescript
282+
import { usePluginContext } from "@supertokens-plugins/profile-details-react";
283+
284+
function CustomProfileComponent() {
285+
const { api, t, fieldInputComponentMap } = usePluginContext();
286+
const [profile, setProfile] = useState(null);
287+
288+
const handleGetDetails = async () => {
289+
const result = await api.getDetails();
290+
if (result.status === "OK") {
291+
setProfile(result.profile);
292+
}
293+
};
294+
295+
const handleUpdateProfile = async (data) => {
296+
const result = await api.updateProfile({ data });
297+
if (result.status === "OK") {
298+
console.log("Profile updated successfully");
299+
}
300+
};
301+
302+
return (
303+
<div>
304+
<h2>{t("PL_CD_SECTION_ACCOUNT_LABEL")}</h2>
305+
<button onClick={handleGetDetails}>Load Profile Details</button>
306+
{/* Your custom form components */}
307+
</div>
308+
);
309+
}
310+
```
311+
312+
## Next steps
313+
314+
Besides profile details management, you can also explore other user management features:
315+
316+
<ReferenceCard.Grid>
317+
<ReferenceCard href="/docs/post-authentication/user-management/progressive-profiling">
318+
<ReferenceCard.Title>
319+
Progressive Profiling
320+
</ReferenceCard.Title>
321+
<ReferenceCard.Description>
322+
Gradually collect user information through customizable forms.
323+
</ReferenceCard.Description>
324+
</ReferenceCard>
325+
326+
<ReferenceCard href="/docs/post-authentication/user-management/user-banning">
327+
<ReferenceCard.Title>
328+
User Banning
329+
</ReferenceCard.Title>
330+
<ReferenceCard.Description>
331+
Implement user banning functionality to restrict access.
332+
</ReferenceCard.Description>
333+
</ReferenceCard>
334+
335+
<ReferenceCard href="/docs/additional-verification/user-roles/introduction">
336+
<ReferenceCard.Title>
337+
User Roles
338+
</ReferenceCard.Title>
339+
<ReferenceCard.Description>
340+
Implement role-based access control for your users.
341+
</ReferenceCard.Description>
342+
</ReferenceCard>
343+
344+
<ReferenceCard href="/docs/references/plugins/introduction">
345+
<ReferenceCard.Title>
346+
Plugins Reference
347+
</ReferenceCard.Title>
348+
<ReferenceCard.Description>
349+
General information on how plugins work.
350+
</ReferenceCard.Description>
351+
</ReferenceCard>
352+
</ReferenceCard.Grid>

docs/references/plugins/captcha-react.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ Defined in: [supertokens-plugins/packages/captcha-react/src/types.ts:82](https:/
489489
### EmailPasswordCaptchaPreAndPostAPIHookActions
490490

491491
```ts
492-
type EmailPasswordCaptchaPreAndPostAPIHookActions = Extract<EmailPasswordPreAndPostAPIHookAction,
492+
type EmailPasswordCaptchaPreAndPostAPIHookActions = Extract<BaseFormSection,
493493
| "EMAIL_PASSWORD_SIGN_UP"
494494
| "EMAIL_PASSWORD_SIGN_IN"
495495
| "SUBMIT_NEW_PASSWORD"
@@ -503,7 +503,7 @@ Defined in: [supertokens-plugins/packages/captcha-react/src/types.ts:50](https:/
503503
### PasswordlessCaptchaPreAndPostAPIHookActions
504504

505505
```ts
506-
type PasswordlessCaptchaPreAndPostAPIHookActions = Extract<PasswordlessPreAndPostAPIHookAction, "PASSWORDLESS_CONSUME_CODE" | "PASSWORDLESS_CREATE_CODE">;
506+
type PasswordlessCaptchaPreAndPostAPIHookActions = Extract<BaseFormSection, "PASSWORDLESS_CONSUME_CODE" | "PASSWORDLESS_CREATE_CODE">;
507507
```
508508

509509
Defined in: [supertokens-plugins/packages/captcha-react/src/types.ts:66](https://github.com/supertokens/supertokens-plugins/blob/main/packages/captcha-react/src/types.ts#L66)

0 commit comments

Comments
 (0)