diff --git a/packages/api/src/routes/auth/callbacks/addUserFieldsToSession.js b/packages/api/src/routes/auth/callbacks/addUserFieldsToSession.js new file mode 100644 index 0000000000..52c2e8a9bd --- /dev/null +++ b/packages/api/src/routes/auth/callbacks/addUserFieldsToSession.js @@ -0,0 +1,23 @@ +/* + Copyright 2020-2022 Lowdefy, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +function addUserFieldsToSession(context, { session, token, authConfig }) { + Object.keys(authConfig.userFields).forEach((fieldName) => { + session.user[fieldName] = token[fieldName]; + }); +} + +export default addUserFieldsToSession; diff --git a/packages/api/src/routes/auth/callbacks/addUserFieldsToToken.js b/packages/api/src/routes/auth/callbacks/addUserFieldsToToken.js new file mode 100644 index 0000000000..0b68718b05 --- /dev/null +++ b/packages/api/src/routes/auth/callbacks/addUserFieldsToToken.js @@ -0,0 +1,27 @@ +/* + Copyright 2020-2022 Lowdefy, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +import { get } from '@lowdefy/helpers'; + +function addUserFieldsToToken(context, { account, authConfig, profile, token }) { + const objects = { account, profile }; + context.logger.debug('Adding userFields to user. Provider data is:'); + context.logger.debug(objects); + Object.values(authConfig.userFields).forEach(([lowdefyFieldName, providerFieldName]) => { + token[lowdefyFieldName] = get(objects, providerFieldName); + }); +} + +export default addUserFieldsToToken; diff --git a/packages/api/src/routes/auth/callbacks/createCallbacks.js b/packages/api/src/routes/auth/callbacks/createCallbacks.js index 0dbe9ea866..288436258d 100644 --- a/packages/api/src/routes/auth/callbacks/createCallbacks.js +++ b/packages/api/src/routes/auth/callbacks/createCallbacks.js @@ -19,17 +19,17 @@ import createRedirectCallback from './createRedirectCallback.js'; import createSessionCallback from './createSessionCallback.js'; import createSignInCallback from './createSignInCallback.js'; -function createCallbacks({ authConfig, plugins }) { +function createCallbacks(context, { authConfig, plugins }) { const callbacks = { - session: createSessionCallback({ authConfig, plugins }), + session: createSessionCallback(context, { authConfig, plugins }), }; - const jwt = createJWTCallback({ authConfig, plugins }); + const jwt = createJWTCallback(context, { authConfig, plugins }); if (jwt) callbacks.jwt = jwt; - const redirect = createRedirectCallback({ authConfig, plugins }); + const redirect = createRedirectCallback(context, { authConfig, plugins }); if (redirect) callbacks.redirect = redirect; - const signIn = createSignInCallback({ authConfig, plugins }); + const signIn = createSignInCallback(context, { authConfig, plugins }); if (signIn) callbacks.signIn = signIn; return callbacks; diff --git a/packages/api/src/routes/auth/callbacks/createJWTCallback.js b/packages/api/src/routes/auth/callbacks/createJWTCallback.js index 922f937181..d199b488ac 100644 --- a/packages/api/src/routes/auth/callbacks/createJWTCallback.js +++ b/packages/api/src/routes/auth/callbacks/createJWTCallback.js @@ -14,9 +14,10 @@ limitations under the License. */ +import addUserFieldsToToken from './addUserFieldsToToken.js'; import createCallbackPlugins from './createCallbackPlugins.js'; -function createJWTCallback({ authConfig, plugins }) { +function createJWTCallback(context, { authConfig, plugins }) { const jwtCallbackPlugins = createCallbackPlugins({ authConfig, plugins, @@ -70,6 +71,9 @@ function createJWTCallback({ authConfig, plugins }) { updated_at, ...token, }; + if (authConfig.userFields) { + addUserFieldsToToken(context, { authConfig, account, profile, token }); + } } for (const plugin of jwtCallbackPlugins) { diff --git a/packages/api/src/routes/auth/callbacks/createRedirectCallback.js b/packages/api/src/routes/auth/callbacks/createRedirectCallback.js index 3750697cab..ad54e8bcea 100644 --- a/packages/api/src/routes/auth/callbacks/createRedirectCallback.js +++ b/packages/api/src/routes/auth/callbacks/createRedirectCallback.js @@ -16,7 +16,7 @@ import createCallbackPlugins from './createCallbackPlugins.js'; -function createRedirectCallback({ authConfig, plugins }) { +function createRedirectCallback(context, { authConfig, plugins }) { const redirectCallbackPlugins = createCallbackPlugins({ authConfig, plugins, diff --git a/packages/api/src/routes/auth/callbacks/createSessionCallback.js b/packages/api/src/routes/auth/callbacks/createSessionCallback.js index ece123f2d4..89702e7d1a 100644 --- a/packages/api/src/routes/auth/callbacks/createSessionCallback.js +++ b/packages/api/src/routes/auth/callbacks/createSessionCallback.js @@ -14,9 +14,10 @@ limitations under the License. */ +import addUserFieldsToSession from './addUserFieldsToSession.js'; import createCallbackPlugins from './createCallbackPlugins.js'; -function createSessionCallback({ authConfig, plugins }) { +function createSessionCallback(context, { authConfig, plugins }) { const sessionCallbackPlugins = createCallbackPlugins({ authConfig, plugins, @@ -70,6 +71,9 @@ function createSessionCallback({ authConfig, plugins }) { updated_at, ...session.user, }; + if (authConfig.userFields) { + addUserFieldsToSession(context, { authConfig, session, token }); + } } for (const plugin of sessionCallbackPlugins) { diff --git a/packages/api/src/routes/auth/callbacks/createSignInCallback.js b/packages/api/src/routes/auth/callbacks/createSignInCallback.js index 008aef2741..9066814531 100644 --- a/packages/api/src/routes/auth/callbacks/createSignInCallback.js +++ b/packages/api/src/routes/auth/callbacks/createSignInCallback.js @@ -16,7 +16,7 @@ import createCallbackPlugins from './createCallbackPlugins.js'; -function createSignInCallback({ authConfig, plugins }) { +function createSignInCallback(context, { authConfig, plugins }) { const signInCallbackPlugins = createCallbackPlugins({ authConfig, plugins, diff --git a/packages/api/src/routes/auth/createProviders.js b/packages/api/src/routes/auth/createProviders.js index 02832b63d8..0b482699c1 100644 --- a/packages/api/src/routes/auth/createProviders.js +++ b/packages/api/src/routes/auth/createProviders.js @@ -19,7 +19,7 @@ // This depends on providerId, which might cause some issues if users copy an example and change the id. // We need to allow users to configure ids, since they might have more than one of the same type. -function createProviders({ authConfig, plugins }) { +function createProviders(context, { authConfig, plugins }) { return authConfig.providers.map((providerConfig) => plugins.providers[providerConfig.type]({ ...providerConfig.properties, diff --git a/packages/api/src/routes/auth/events/createCreateUserEvent.js b/packages/api/src/routes/auth/events/createCreateUserEvent.js index 8b5df56d2b..91262c3852 100644 --- a/packages/api/src/routes/auth/events/createCreateUserEvent.js +++ b/packages/api/src/routes/auth/events/createCreateUserEvent.js @@ -16,7 +16,7 @@ import createEventPlugins from './createEventPlugins.js'; -function createCreateUserEvent({ authConfig, plugins }) { +function createCreateUserEvent(context, { authConfig, plugins }) { const createUserPlugins = createEventPlugins({ authConfig, plugins, diff --git a/packages/api/src/routes/auth/events/createEvents.js b/packages/api/src/routes/auth/events/createEvents.js index 3b9e24fe5c..ce8af608c9 100644 --- a/packages/api/src/routes/auth/events/createEvents.js +++ b/packages/api/src/routes/auth/events/createEvents.js @@ -21,25 +21,25 @@ import createSignInEvent from './createSignInEvent.js'; import createSignOutEvent from './createSignOutEvent.js'; import createUpdateUserEvent from './createUpdateUserEvent.js'; -function createEvents({ authConfig, plugins }) { +function createEvents(context, { authConfig, plugins }) { const events = {}; - const createUser = createCreateUserEvent({ authConfig, plugins }); + const createUser = createCreateUserEvent(context, { authConfig, plugins }); if (createUser) events.createUser = createUser; - const linkAccount = createLinkAccountEvent({ authConfig, plugins }); + const linkAccount = createLinkAccountEvent(context, { authConfig, plugins }); if (linkAccount) events.linkAccount = linkAccount; - const session = createSessionEvent({ authConfig, plugins }); + const session = createSessionEvent(context, { authConfig, plugins }); if (session) events.session = session; - const signIn = createSignInEvent({ authConfig, plugins }); + const signIn = createSignInEvent(context, { authConfig, plugins }); if (signIn) events.signIn = signIn; - const signOut = createSignOutEvent({ authConfig, plugins }); + const signOut = createSignOutEvent(context, { authConfig, plugins }); if (signOut) events.signOut = signOut; - const updateUser = createUpdateUserEvent({ authConfig, plugins }); + const updateUser = createUpdateUserEvent(context, { authConfig, plugins }); if (updateUser) events.updateUser = updateUser; return events; diff --git a/packages/api/src/routes/auth/events/createLinkAccountEvent.js b/packages/api/src/routes/auth/events/createLinkAccountEvent.js index cb117e6cc5..7546cbe4b2 100644 --- a/packages/api/src/routes/auth/events/createLinkAccountEvent.js +++ b/packages/api/src/routes/auth/events/createLinkAccountEvent.js @@ -16,7 +16,7 @@ import createEventPlugins from './createEventPlugins.js'; -function createLinkAccountEvent({ authConfig, plugins }) { +function createLinkAccountEvent(context, { authConfig, plugins }) { const linkAccountPlugins = createEventPlugins({ authConfig, plugins, diff --git a/packages/api/src/routes/auth/events/createSessionEvent.js b/packages/api/src/routes/auth/events/createSessionEvent.js index 689350cd6d..19e7192497 100644 --- a/packages/api/src/routes/auth/events/createSessionEvent.js +++ b/packages/api/src/routes/auth/events/createSessionEvent.js @@ -16,7 +16,7 @@ import createEventPlugins from './createEventPlugins.js'; -function createSessionEvent({ authConfig, plugins }) { +function createSessionEvent(context, { authConfig, plugins }) { const sessionPlugins = createEventPlugins({ authConfig, plugins, diff --git a/packages/api/src/routes/auth/events/createSignInEvent.js b/packages/api/src/routes/auth/events/createSignInEvent.js index 9098380e67..49b07c0f46 100644 --- a/packages/api/src/routes/auth/events/createSignInEvent.js +++ b/packages/api/src/routes/auth/events/createSignInEvent.js @@ -16,7 +16,7 @@ import createEventPlugins from './createEventPlugins.js'; -function createSignInEvent({ authConfig, plugins }) { +function createSignInEvent(context, { authConfig, plugins }) { const signInPlugins = createEventPlugins({ authConfig, plugins, diff --git a/packages/api/src/routes/auth/events/createSignOutEvent.js b/packages/api/src/routes/auth/events/createSignOutEvent.js index ea388cb7b3..a080e2ae7d 100644 --- a/packages/api/src/routes/auth/events/createSignOutEvent.js +++ b/packages/api/src/routes/auth/events/createSignOutEvent.js @@ -16,7 +16,7 @@ import createEventPlugins from './createEventPlugins.js'; -function createSignOutEvent({ authConfig, plugins }) { +function createSignOutEvent(context, { authConfig, plugins }) { const signInPlugins = createEventPlugins({ authConfig, plugins, diff --git a/packages/api/src/routes/auth/events/createUpdateUserEvent.js b/packages/api/src/routes/auth/events/createUpdateUserEvent.js index 83d17a4eb9..4bd3fe6d6d 100644 --- a/packages/api/src/routes/auth/events/createUpdateUserEvent.js +++ b/packages/api/src/routes/auth/events/createUpdateUserEvent.js @@ -16,7 +16,7 @@ import createEventPlugins from './createEventPlugins.js'; -function createUpdateUserEvent({ authConfig, plugins }) { +function createUpdateUserEvent(context, { authConfig, plugins }) { const updateUserPlugins = createEventPlugins({ authConfig, plugins, diff --git a/packages/api/src/routes/auth/getNextAuthConfig.js b/packages/api/src/routes/auth/getNextAuthConfig.js index 17da50ef73..32cad3c15a 100644 --- a/packages/api/src/routes/auth/getNextAuthConfig.js +++ b/packages/api/src/routes/auth/getNextAuthConfig.js @@ -25,10 +25,11 @@ import createProviders from './createProviders.js'; const nextAuthConfig = {}; let initialized = false; -function getNextAuthConfig({ authJson, plugins }) { +function getNextAuthConfig(context, { authJson, plugins }) { if (initialized) return nextAuthConfig; const secrets = getSecretsFromEnv(); + // TODO: Add logger const operatorsParser = new NodeParser({ operators: { _secret }, payload: {}, @@ -45,9 +46,9 @@ function getNextAuthConfig({ authJson, plugins }) { throw new Error(operatorErrors[0]); } - nextAuthConfig.callbacks = createCallbacks({ authConfig, plugins }); - nextAuthConfig.events = createEvents({ authConfig, plugins }); - nextAuthConfig.providers = createProviders({ authConfig, plugins }); + nextAuthConfig.callbacks = createCallbacks(context, { authConfig, plugins }); + nextAuthConfig.events = createEvents(context, { authConfig, plugins }); + nextAuthConfig.providers = createProviders(context, { authConfig, plugins }); nextAuthConfig.session = authConfig.session; nextAuthConfig.theme = authConfig.theme; diff --git a/packages/build/src/lowdefySchema.js b/packages/build/src/lowdefySchema.js index 4d13b3344d..8750db9cab 100644 --- a/packages/build/src/lowdefySchema.js +++ b/packages/build/src/lowdefySchema.js @@ -225,6 +225,9 @@ export default { theme: { type: 'object', }, + userFields: { + type: 'object', + }, }, }, block: { diff --git a/packages/server-dev/pages/api/auth/[...nextauth].js b/packages/server-dev/pages/api/auth/[...nextauth].js index bf419a670f..21be812381 100644 --- a/packages/server-dev/pages/api/auth/[...nextauth].js +++ b/packages/server-dev/pages/api/auth/[...nextauth].js @@ -22,4 +22,7 @@ import callbacks from '../../../build/plugins/auth/callbacks.js'; import events from '../../../build/plugins/auth/events.js'; import providers from '../../../build/plugins/auth/providers.js'; -export default NextAuth(getNextAuthConfig({ authJson, plugins: { callbacks, events, providers } })); +// TODO: make createApiContext synchronous +export default NextAuth( + getNextAuthConfig({ logger: console }, { authJson, plugins: { callbacks, events, providers } }) +);