@jskit-ai/users-core 0.1.64 → 0.1.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.descriptor.mjs +14 -65
- package/package.json +10 -10
- package/src/server/UsersCoreServiceProvider.js +18 -2
- package/src/server/accountNotifications/accountNotificationsActions.js +3 -5
- package/src/server/accountNotifications/accountNotificationsService.js +3 -2
- package/src/server/accountNotifications/bootAccountNotificationsRoutes.js +12 -11
- package/src/server/accountPreferences/accountPreferencesActions.js +3 -5
- package/src/server/accountPreferences/accountPreferencesService.js +3 -2
- package/src/server/accountPreferences/bootAccountPreferencesRoutes.js +12 -11
- package/src/server/accountProfile/accountProfileActions.js +15 -32
- package/src/server/accountProfile/accountProfileService.js +9 -8
- package/src/server/accountProfile/bootAccountProfileRoutes.js +25 -19
- package/src/server/accountSecurity/accountSecurityActions.js +21 -16
- package/src/server/accountSecurity/accountSecurityService.js +16 -6
- package/src/server/accountSecurity/bootAccountSecurityRoutes.js +52 -40
- package/src/server/common/formatters/accountSettingsResponseFormatter.js +8 -18
- package/src/server/common/registerCommonRepositories.js +5 -2
- package/src/server/common/repositories/userProfilesRepository.js +227 -88
- package/src/server/common/repositories/userSettingsRepository.js +108 -100
- package/src/server/common/support/accountSettingsJsonApiTransport.js +10 -0
- package/src/server/usersBootstrapContributor.js +13 -32
- package/src/shared/resources/accountSettingsSchemas.js +83 -0
- package/src/shared/resources/userProfileResource.js +146 -126
- package/src/shared/resources/userSettingsResource.js +376 -353
- package/templates/packages/users/package.descriptor.mjs +4 -5
- package/templates/packages/users/package.json +0 -1
- package/templates/packages/users/src/server/UsersProvider.js +23 -24
- package/templates/packages/users/src/server/actions.js +26 -28
- package/templates/packages/users/src/server/registerRoutes.js +29 -15
- package/templates/packages/users/src/server/repository.js +35 -28
- package/templates/packages/users/src/server/service.js +20 -15
- package/templates/packages/users/src/shared/userResource.js +55 -68
- package/templates/packages/users-workspace/package.descriptor.mjs +4 -5
- package/templates/packages/users-workspace/src/server/UsersProvider.js +23 -24
- package/templates/packages/users-workspace/src/server/actions.js +28 -28
- package/templates/packages/users-workspace/src/server/registerRoutes.js +34 -16
- package/test/accountSecurityService.test.js +32 -0
- package/test/providerLifecycle.test.js +63 -0
- package/test/registerCommonRepositories.test.js +28 -8
- package/test/repositoryContracts.test.js +177 -28
- package/test/resourcesCanonical.test.js +18 -11
- package/test/userSettingsInternalResource.test.js +8 -0
- package/test/userSettingsResource.test.js +24 -7
- package/test/usersBootstrapContributor.test.js +40 -1
- package/test/usersPackageScaffoldContract.test.js +70 -3
- package/test/usersRouteRequestInputValidator.test.js +92 -23
- package/test/usersRouteResources.test.js +28 -18
- package/src/server/common/resources/userProfilesResource.js +0 -203
- package/src/server/common/validators/authenticatedUserValidator.js +0 -43
- package/src/shared/resources/resolveGlobalArrayRegistry.js +0 -6
- package/src/shared/resources/userSettingsFields.js +0 -76
- package/templates/packages/main/src/shared/resources/userSettingsFields.js +0 -138
- package/templates/packages/users/src/server/actionIds.js +0 -6
- package/templates/packages/users/src/server/listConfig.js +0 -16
- package/test/settingsFieldRegistriesSingleton.test.js +0 -14
- package/test-support/registerDefaultSettingsFields.js +0 -2
|
@@ -1,156 +1,164 @@
|
|
|
1
1
|
import {
|
|
2
|
-
normalizeDbRecordId,
|
|
3
2
|
normalizeRecordId,
|
|
4
|
-
toIsoString,
|
|
5
3
|
nowDb,
|
|
6
4
|
isDuplicateEntryError,
|
|
7
5
|
createWithTransaction
|
|
8
6
|
} from "./repositoryUtils.js";
|
|
9
|
-
import { DEFAULT_USER_SETTINGS } from "../../../shared/settings.js";
|
|
10
7
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const mapped = {
|
|
20
|
-
userId: normalizeDbRecordId(row.user_id, { fallback: "" }),
|
|
21
|
-
passwordSignInEnabled: row.password_sign_in_enabled == null ? true : Boolean(row.password_sign_in_enabled),
|
|
22
|
-
passwordSetupRequired: row.password_setup_required == null ? false : Boolean(row.password_setup_required),
|
|
23
|
-
createdAt: toIsoString(row.created_at),
|
|
24
|
-
updatedAt: toIsoString(row.updated_at)
|
|
25
|
-
};
|
|
8
|
+
createJsonApiInputRecord,
|
|
9
|
+
createJsonRestContext,
|
|
10
|
+
simplifyJsonApiDocument
|
|
11
|
+
} from "@jskit-ai/json-rest-api-core/server/jsonRestApiHost";
|
|
12
|
+
import { DEFAULT_USER_SETTINGS } from "../../../shared/settings.js";
|
|
26
13
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
14
|
+
const RESOURCE_TYPE = "userSettings";
|
|
15
|
+
const USER_SETTINGS_PATCH_FIELDS = Object.freeze([
|
|
16
|
+
"theme",
|
|
17
|
+
"locale",
|
|
18
|
+
"timeZone",
|
|
19
|
+
"dateFormat",
|
|
20
|
+
"numberFormat",
|
|
21
|
+
"currencyCode",
|
|
22
|
+
"avatarSize",
|
|
23
|
+
"productUpdates",
|
|
24
|
+
"accountActivity",
|
|
25
|
+
"securityAlerts",
|
|
26
|
+
"passwordSignInEnabled",
|
|
27
|
+
"passwordSetupRequired"
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
function pickPatchFields(source = {}) {
|
|
31
|
+
const patch = {};
|
|
32
|
+
|
|
33
|
+
for (const fieldName of USER_SETTINGS_PATCH_FIELDS) {
|
|
34
|
+
if (Object.hasOwn(source, fieldName)) {
|
|
35
|
+
patch[fieldName] = source[fieldName];
|
|
36
|
+
}
|
|
39
37
|
}
|
|
40
38
|
|
|
41
|
-
return
|
|
39
|
+
return patch;
|
|
42
40
|
}
|
|
43
41
|
|
|
44
|
-
function
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
password_sign_in_enabled: DEFAULT_USER_SETTINGS.passwordSignInEnabled,
|
|
60
|
-
password_setup_required: DEFAULT_USER_SETTINGS.passwordSetupRequired,
|
|
61
|
-
created_at: nowDb(),
|
|
62
|
-
updated_at: nowDb()
|
|
42
|
+
function createDefaultUserSettingsCreatePayload(userId) {
|
|
43
|
+
return {
|
|
44
|
+
id: userId,
|
|
45
|
+
theme: DEFAULT_USER_SETTINGS.theme,
|
|
46
|
+
locale: DEFAULT_USER_SETTINGS.locale,
|
|
47
|
+
timeZone: DEFAULT_USER_SETTINGS.timeZone,
|
|
48
|
+
dateFormat: DEFAULT_USER_SETTINGS.dateFormat,
|
|
49
|
+
numberFormat: DEFAULT_USER_SETTINGS.numberFormat,
|
|
50
|
+
currencyCode: DEFAULT_USER_SETTINGS.currencyCode,
|
|
51
|
+
avatarSize: DEFAULT_USER_SETTINGS.avatarSize,
|
|
52
|
+
productUpdates: DEFAULT_USER_SETTINGS.productUpdates,
|
|
53
|
+
accountActivity: DEFAULT_USER_SETTINGS.accountActivity,
|
|
54
|
+
securityAlerts: DEFAULT_USER_SETTINGS.securityAlerts,
|
|
55
|
+
passwordSignInEnabled: DEFAULT_USER_SETTINGS.passwordSignInEnabled,
|
|
56
|
+
passwordSetupRequired: DEFAULT_USER_SETTINGS.passwordSetupRequired
|
|
63
57
|
};
|
|
64
|
-
|
|
65
|
-
const resolvedDefaults = {};
|
|
66
|
-
for (const field of userSettingsFields) {
|
|
67
|
-
const defaultValue = field.resolveDefault({
|
|
68
|
-
settings: resolvedDefaults
|
|
69
|
-
});
|
|
70
|
-
payload[field.repository.column] = field.normalizeInput(defaultValue, {
|
|
71
|
-
payload: resolvedDefaults,
|
|
72
|
-
settings: resolvedDefaults
|
|
73
|
-
});
|
|
74
|
-
resolvedDefaults[field.key] = field.normalizeOutput(defaultValue, {
|
|
75
|
-
settings: resolvedDefaults
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return payload;
|
|
80
58
|
}
|
|
81
59
|
|
|
82
|
-
function createRepository(knex) {
|
|
60
|
+
function createRepository({ api, knex } = {}) {
|
|
61
|
+
if (!api?.resources?.userSettings) {
|
|
62
|
+
throw new TypeError("userSettingsRepository requires json-rest-api userSettings resource.");
|
|
63
|
+
}
|
|
83
64
|
if (typeof knex !== "function") {
|
|
84
65
|
throw new TypeError("userSettingsRepository requires knex.");
|
|
85
66
|
}
|
|
86
67
|
const withTransaction = createWithTransaction(knex);
|
|
87
68
|
|
|
69
|
+
async function queryFirst(filters = {}, options = {}) {
|
|
70
|
+
const result = await api.resources.userSettings.query(
|
|
71
|
+
{
|
|
72
|
+
queryParams: {
|
|
73
|
+
filters
|
|
74
|
+
},
|
|
75
|
+
transaction: options?.trx || null,
|
|
76
|
+
simplified: false
|
|
77
|
+
},
|
|
78
|
+
createJsonRestContext(options?.context || null)
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const rows = simplifyJsonApiDocument(result);
|
|
82
|
+
return Array.isArray(rows) ? rows[0] || null : null;
|
|
83
|
+
}
|
|
84
|
+
|
|
88
85
|
async function findByUserId(userId, options = {}) {
|
|
89
|
-
const client = options?.trx || knex;
|
|
90
86
|
const normalizedUserId = normalizeRecordId(userId, { fallback: null });
|
|
91
87
|
if (!normalizedUserId) {
|
|
92
88
|
return null;
|
|
93
89
|
}
|
|
94
90
|
|
|
95
|
-
|
|
96
|
-
return mapRow(row);
|
|
91
|
+
return queryFirst({ id: normalizedUserId }, options);
|
|
97
92
|
}
|
|
98
93
|
|
|
99
94
|
async function ensureForUserId(userId, options = {}) {
|
|
100
|
-
const client = options?.trx || knex;
|
|
101
95
|
const normalizedUserId = normalizeRecordId(userId, { fallback: null });
|
|
102
96
|
if (!normalizedUserId) {
|
|
103
97
|
throw new TypeError("userSettingsRepository.ensureForUserId requires a valid user id.");
|
|
104
98
|
}
|
|
105
99
|
|
|
106
|
-
const existing = await findByUserId(normalizedUserId,
|
|
100
|
+
const existing = await findByUserId(normalizedUserId, options);
|
|
107
101
|
if (existing) {
|
|
108
102
|
return existing;
|
|
109
103
|
}
|
|
110
104
|
|
|
111
105
|
try {
|
|
112
|
-
await
|
|
106
|
+
await api.resources.userSettings.post(
|
|
107
|
+
{
|
|
108
|
+
inputRecord: createJsonApiInputRecord(
|
|
109
|
+
RESOURCE_TYPE,
|
|
110
|
+
createDefaultUserSettingsCreatePayload(normalizedUserId),
|
|
111
|
+
{
|
|
112
|
+
id: normalizedUserId
|
|
113
|
+
}
|
|
114
|
+
),
|
|
115
|
+
transaction: options?.trx || null,
|
|
116
|
+
simplified: false
|
|
117
|
+
},
|
|
118
|
+
createJsonRestContext(options?.context || null)
|
|
119
|
+
);
|
|
113
120
|
} catch (error) {
|
|
114
121
|
if (!isDuplicateEntryError(error)) {
|
|
115
122
|
throw error;
|
|
116
123
|
}
|
|
117
124
|
}
|
|
118
125
|
|
|
119
|
-
return findByUserId(normalizedUserId,
|
|
126
|
+
return findByUserId(normalizedUserId, options);
|
|
120
127
|
}
|
|
121
128
|
|
|
122
129
|
async function patchUserSettings(userId, patch = {}, options = {}) {
|
|
123
|
-
const client = options?.trx || knex;
|
|
124
130
|
const normalizedUserId = normalizeRecordId(userId, { fallback: null });
|
|
125
131
|
if (!normalizedUserId) {
|
|
126
132
|
throw new TypeError("userSettingsRepository.patchUserSettings requires a valid user id.");
|
|
127
133
|
}
|
|
128
134
|
|
|
129
|
-
|
|
135
|
+
await ensureForUserId(normalizedUserId, options);
|
|
130
136
|
const source = patch && typeof patch === "object" ? patch : {};
|
|
137
|
+
const updatePayload = pickPatchFields(source);
|
|
131
138
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
for (const field of userSettingsFields) {
|
|
137
|
-
if (!Object.hasOwn(source, field.key)) {
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
dbPatch[field.repository.column] = field.normalizeInput(source[field.key], {
|
|
141
|
-
payload: source,
|
|
142
|
-
settings: ensured
|
|
143
|
-
});
|
|
139
|
+
if (Object.keys(updatePayload).length < 1) {
|
|
140
|
+
return findByUserId(normalizedUserId, options);
|
|
144
141
|
}
|
|
145
142
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
143
|
+
await api.resources.userSettings.patch(
|
|
144
|
+
{
|
|
145
|
+
inputRecord: createJsonApiInputRecord(
|
|
146
|
+
RESOURCE_TYPE,
|
|
147
|
+
{
|
|
148
|
+
...updatePayload,
|
|
149
|
+
updatedAt: nowDb()
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
id: normalizedUserId
|
|
153
|
+
}
|
|
154
|
+
),
|
|
155
|
+
transaction: options?.trx || null,
|
|
156
|
+
simplified: false
|
|
157
|
+
},
|
|
158
|
+
createJsonRestContext(options?.context || null)
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
return findByUserId(normalizedUserId, options);
|
|
154
162
|
}
|
|
155
163
|
|
|
156
164
|
async function updatePreferences(userId, patch = {}, options = {}) {
|
|
@@ -166,9 +174,9 @@ function createRepository(knex) {
|
|
|
166
174
|
userId,
|
|
167
175
|
{
|
|
168
176
|
passwordSignInEnabled: enabled,
|
|
169
|
-
|
|
170
|
-
? options.passwordSetupRequired
|
|
171
|
-
:
|
|
177
|
+
...(Object.hasOwn(options, "passwordSetupRequired")
|
|
178
|
+
? { passwordSetupRequired: options.passwordSetupRequired }
|
|
179
|
+
: {})
|
|
172
180
|
},
|
|
173
181
|
options
|
|
174
182
|
);
|
|
@@ -190,4 +198,4 @@ function createRepository(knex) {
|
|
|
190
198
|
});
|
|
191
199
|
}
|
|
192
200
|
|
|
193
|
-
export { createRepository
|
|
201
|
+
export { createRepository };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
function resolveAccountSettingsResourceId(_record, context = {}) {
|
|
2
|
+
const userId = context?.request?.user?.id;
|
|
3
|
+
if (userId == null || String(userId).trim() === "") {
|
|
4
|
+
throw new Error("JSON:API account settings response requires request.user.id.");
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
return userId;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { resolveAccountSettingsResourceId };
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { AppError } from "@jskit-ai/kernel/server/runtime";
|
|
2
2
|
import { requireServiceMethod } from "@jskit-ai/kernel/shared/actions/actionContributorHelpers";
|
|
3
3
|
import { normalizeLowerText, normalizeText } from "@jskit-ai/kernel/shared/actions/textNormalization";
|
|
4
|
-
import { normalizeObject } from "@jskit-ai/kernel/shared/support/normalize";
|
|
4
|
+
import { normalizeBoolean, normalizeObject } from "@jskit-ai/kernel/shared/support/normalize";
|
|
5
5
|
import { accountAvatarFormatter } from "./common/formatters/accountAvatarFormatter.js";
|
|
6
|
-
import {
|
|
7
|
-
import { userSettingsFields } from "../shared/resources/userSettingsFields.js";
|
|
6
|
+
import { USER_SETTINGS_BOOTSTRAP_KEYS } from "../shared/resources/userSettingsResource.js";
|
|
8
7
|
|
|
9
8
|
function getOAuthProviderCatalogPayload(authService) {
|
|
10
9
|
if (!authService || typeof authService.getOAuthProviderCatalog !== "function") {
|
|
@@ -31,28 +30,20 @@ function getOAuthProviderCatalogPayload(authService) {
|
|
|
31
30
|
};
|
|
32
31
|
}
|
|
33
32
|
|
|
34
|
-
function
|
|
35
|
-
if (
|
|
36
|
-
return
|
|
33
|
+
function resolveBooleanConfigValue(value, fallback) {
|
|
34
|
+
if (value === undefined || value === null || value === "") {
|
|
35
|
+
return fallback;
|
|
37
36
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (normalized === "true") {
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
if (normalized === "false") {
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return fallback;
|
|
37
|
+
|
|
38
|
+
return normalizeBoolean(value);
|
|
48
39
|
}
|
|
49
40
|
|
|
50
41
|
function resolveAppState(appConfig = {}) {
|
|
51
42
|
const features = {
|
|
52
|
-
assistantEnabled:
|
|
43
|
+
assistantEnabled: resolveBooleanConfigValue(appConfig.assistantEnabled, false),
|
|
53
44
|
assistantRequiredPermission: normalizeText(appConfig.assistantRequiredPermission),
|
|
54
|
-
socialEnabled:
|
|
55
|
-
socialFederationEnabled:
|
|
45
|
+
socialEnabled: resolveBooleanConfigValue(appConfig.socialEnabled, false),
|
|
46
|
+
socialFederationEnabled: resolveBooleanConfigValue(appConfig.socialFederationEnabled, false)
|
|
56
47
|
};
|
|
57
48
|
|
|
58
49
|
return {
|
|
@@ -79,18 +70,8 @@ function mapUserSettingsBootstrap(settings = {}) {
|
|
|
79
70
|
const source = settings && typeof settings === "object" ? settings : {};
|
|
80
71
|
const mapped = {};
|
|
81
72
|
|
|
82
|
-
for (const
|
|
83
|
-
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
const rawValue = Object.hasOwn(source, field.key)
|
|
87
|
-
? source[field.key]
|
|
88
|
-
: field.resolveDefault({
|
|
89
|
-
settings: source
|
|
90
|
-
});
|
|
91
|
-
mapped[field.key] = field.normalizeOutput(rawValue, {
|
|
92
|
-
settings: source
|
|
93
|
-
});
|
|
73
|
+
for (const fieldKey of USER_SETTINGS_BOOTSTRAP_KEYS) {
|
|
74
|
+
mapped[fieldKey] = source[fieldKey];
|
|
94
75
|
}
|
|
95
76
|
|
|
96
77
|
return mapped;
|
|
@@ -130,7 +111,7 @@ function createUsersBootstrapContributor({
|
|
|
130
111
|
throw new AppError(503, "Authentication service temporarily unavailable. Please retry.");
|
|
131
112
|
}
|
|
132
113
|
|
|
133
|
-
const normalizedUser =
|
|
114
|
+
const normalizedUser = authResult?.authenticated === true ? authResult?.profile || null : null;
|
|
134
115
|
const inheritedSurfaceAccess = normalizeObject(existingPayload?.surfaceAccess);
|
|
135
116
|
let payload = createAnonymousBootstrapPayload({
|
|
136
117
|
appState,
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createSchema } from "json-rest-schema";
|
|
2
|
+
|
|
3
|
+
const accountAvatarOutputSchema = createSchema({
|
|
4
|
+
uploadedUrl: { type: "string", required: true, nullable: true },
|
|
5
|
+
gravatarUrl: { type: "string", required: true, minLength: 1 },
|
|
6
|
+
effectiveUrl: { type: "string", required: true, minLength: 1 },
|
|
7
|
+
hasUploadedAvatar: { type: "boolean", required: true },
|
|
8
|
+
size: { type: "number", required: true, min: 1 },
|
|
9
|
+
version: { type: "string", required: true, nullable: true }
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const userProfileOutputSchema = createSchema({
|
|
13
|
+
displayName: { type: "string", required: true },
|
|
14
|
+
email: { type: "string", required: true },
|
|
15
|
+
emailManagedBy: { type: "string", required: true },
|
|
16
|
+
emailChangeFlow: { type: "string", required: true },
|
|
17
|
+
avatar: {
|
|
18
|
+
type: "object",
|
|
19
|
+
required: true,
|
|
20
|
+
schema: accountAvatarOutputSchema
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const accountSecurityMfaSchema = createSchema({
|
|
25
|
+
status: { type: "string", required: true },
|
|
26
|
+
enrolled: { type: "boolean", required: true },
|
|
27
|
+
methods: {
|
|
28
|
+
type: "array",
|
|
29
|
+
required: true,
|
|
30
|
+
items: { type: "string", minLength: 1 }
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const accountSecuritySessionsSchema = createSchema({
|
|
35
|
+
canSignOutOtherDevices: { type: "boolean", required: true }
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const accountSecurityAuthPolicySchema = createSchema({
|
|
39
|
+
minimumEnabledMethods: { type: "integer", required: true, min: 1 },
|
|
40
|
+
enabledMethodsCount: { type: "integer", required: true, min: 0 }
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const accountSecurityAuthMethodSchema = createSchema({
|
|
44
|
+
id: { type: "string", required: true },
|
|
45
|
+
kind: { type: "string", required: true },
|
|
46
|
+
provider: { type: "string", required: true, nullable: true },
|
|
47
|
+
label: { type: "string", required: true },
|
|
48
|
+
configured: { type: "boolean", required: true },
|
|
49
|
+
enabled: { type: "boolean", required: true },
|
|
50
|
+
canEnable: { type: "boolean", required: true },
|
|
51
|
+
canDisable: { type: "boolean", required: true },
|
|
52
|
+
supportsSecretUpdate: { type: "boolean", required: true },
|
|
53
|
+
requiresCurrentPassword: { type: "boolean", required: true }
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const accountSecurityStatusSchema = createSchema({
|
|
57
|
+
mfa: {
|
|
58
|
+
type: "object",
|
|
59
|
+
required: true,
|
|
60
|
+
schema: accountSecurityMfaSchema
|
|
61
|
+
},
|
|
62
|
+
sessions: {
|
|
63
|
+
type: "object",
|
|
64
|
+
required: true,
|
|
65
|
+
schema: accountSecuritySessionsSchema
|
|
66
|
+
},
|
|
67
|
+
authPolicy: {
|
|
68
|
+
type: "object",
|
|
69
|
+
required: true,
|
|
70
|
+
schema: accountSecurityAuthPolicySchema
|
|
71
|
+
},
|
|
72
|
+
authMethods: {
|
|
73
|
+
type: "array",
|
|
74
|
+
required: true,
|
|
75
|
+
items: accountSecurityAuthMethodSchema
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
export {
|
|
80
|
+
accountAvatarOutputSchema,
|
|
81
|
+
userProfileOutputSchema,
|
|
82
|
+
accountSecurityStatusSchema
|
|
83
|
+
};
|