mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-04-06 15:30:30 +08:00
feat(build): Build auth providers and write plugin import file.
This commit is contained in:
parent
f27cc6066e
commit
9eb34c8700
@ -16,43 +16,14 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { type } from '@lowdefy/helpers';
|
||||
import getPageRoles from './getPageRoles.js';
|
||||
import getProtectedPages from './getProtectedPages.js';
|
||||
import buildAuthPlugins from './buildAuthPlugins.js';
|
||||
import buildPageAuth from './buildPageAuth.js';
|
||||
import validateAuthConfig from './validateAuthConfig.js';
|
||||
|
||||
function buildAuth({ components }) {
|
||||
function buildAuth({ components, context }) {
|
||||
validateAuthConfig({ components });
|
||||
const protectedPages = getProtectedPages({ components });
|
||||
const pageRoles = getPageRoles({ components });
|
||||
let configPublicPages = [];
|
||||
if (type.isArray(components.auth.pages.public)) {
|
||||
configPublicPages = components.auth.pages.public;
|
||||
}
|
||||
|
||||
(components.pages || []).forEach((page) => {
|
||||
if (pageRoles[page.id]) {
|
||||
if (configPublicPages.includes(page.id)) {
|
||||
throw new Error(
|
||||
`Page "${page.id}" is both protected by roles ${JSON.stringify(
|
||||
pageRoles[page.id]
|
||||
)} and public.`
|
||||
);
|
||||
}
|
||||
page.auth = {
|
||||
public: false,
|
||||
roles: pageRoles[page.id],
|
||||
};
|
||||
} else if (protectedPages.includes(page.id)) {
|
||||
page.auth = {
|
||||
public: false,
|
||||
};
|
||||
} else {
|
||||
page.auth = {
|
||||
public: true,
|
||||
};
|
||||
}
|
||||
});
|
||||
buildPageAuth({ components });
|
||||
buildAuthPlugins({ components, context });
|
||||
|
||||
return components;
|
||||
}
|
||||
|
41
packages/build/src/build/buildAuth/buildAuthPlugins.js
Normal file
41
packages/build/src/build/buildAuth/buildAuthPlugins.js
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
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 { type } from '@lowdefy/helpers';
|
||||
|
||||
function buildAuthPlugins({ components, context }) {
|
||||
if (type.isArray(components.auth.providers)) {
|
||||
components.auth.providers.forEach((provider) => {
|
||||
if (type.isUndefined(provider.id)) {
|
||||
throw new Error(`Connection id missing.`);
|
||||
}
|
||||
if (!type.isString(provider.id)) {
|
||||
throw new Error(
|
||||
`Auth provider id is not a string. Received ${JSON.stringify(provider.id)}.`
|
||||
);
|
||||
}
|
||||
if (!type.isString(provider.type)) {
|
||||
throw new Error(
|
||||
`Auth provider type is not a string at provider "${
|
||||
provider.id
|
||||
}". Received ${JSON.stringify(provider.type)}.`
|
||||
);
|
||||
}
|
||||
context.typeCounters.auth.providers.increment(provider.type);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default buildAuthPlugins;
|
58
packages/build/src/build/buildAuth/buildPageAuth.js
Normal file
58
packages/build/src/build/buildAuth/buildPageAuth.js
Normal file
@ -0,0 +1,58 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
|
||||
/*
|
||||
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 { type } from '@lowdefy/helpers';
|
||||
import getPageRoles from './getPageRoles.js';
|
||||
import getProtectedPages from './getProtectedPages.js';
|
||||
|
||||
function buildPageAuth({ components }) {
|
||||
const protectedPages = getProtectedPages({ components });
|
||||
const pageRoles = getPageRoles({ components });
|
||||
let configPublicPages = [];
|
||||
if (type.isArray(components.auth.pages.public)) {
|
||||
configPublicPages = components.auth.pages.public;
|
||||
}
|
||||
|
||||
(components.pages || []).forEach((page) => {
|
||||
if (pageRoles[page.id]) {
|
||||
if (configPublicPages.includes(page.id)) {
|
||||
throw new Error(
|
||||
`Page "${page.id}" is both protected by roles ${JSON.stringify(
|
||||
pageRoles[page.id]
|
||||
)} and public.`
|
||||
);
|
||||
}
|
||||
page.auth = {
|
||||
public: false,
|
||||
roles: pageRoles[page.id],
|
||||
};
|
||||
} else if (protectedPages.includes(page.id)) {
|
||||
page.auth = {
|
||||
public: false,
|
||||
};
|
||||
} else {
|
||||
page.auth = {
|
||||
public: true,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
export default buildPageAuth;
|
@ -33,10 +33,17 @@ async function validateAuthConfig({ components }) {
|
||||
if (type.isNone(components.auth.pages.roles)) {
|
||||
components.auth.pages.roles = {};
|
||||
}
|
||||
validate({
|
||||
|
||||
const { valid } = validate({
|
||||
schema: lowdefySchema.definitions.authConfig,
|
||||
data: components.auth,
|
||||
returnErrors: true,
|
||||
});
|
||||
|
||||
if (!valid) {
|
||||
throw new Error('lowdefy.auth does not match schema.'); // TODO: Better error message
|
||||
}
|
||||
|
||||
if (
|
||||
(components.auth.pages.protected === true && components.auth.pages.public === true) ||
|
||||
(type.isArray(components.auth.pages.protected) && type.isArray(components.auth.pages.public))
|
||||
|
@ -52,6 +52,9 @@ function buildTypes({ components, context }) {
|
||||
|
||||
components.types = {
|
||||
actions: {},
|
||||
auth: {
|
||||
providers: {},
|
||||
},
|
||||
blocks: {},
|
||||
connections: {},
|
||||
requests: {},
|
||||
@ -68,6 +71,13 @@ function buildTypes({ components, context }) {
|
||||
typeClass: 'Action',
|
||||
});
|
||||
|
||||
buildTypeClass(context, {
|
||||
counter: typeCounters.auth.providers,
|
||||
definitions: context.typesMap.auth.providers,
|
||||
store: components.types.auth.providers,
|
||||
typeClass: 'Auth provider',
|
||||
});
|
||||
|
||||
buildTypeClass(context, {
|
||||
counter: typeCounters.blocks,
|
||||
definitions: context.typesMap.blocks,
|
||||
|
@ -24,12 +24,12 @@ async function testSchema({ components, context }) {
|
||||
data: components,
|
||||
returnErrors: true,
|
||||
});
|
||||
|
||||
if (!valid) {
|
||||
await context.logger.warn('Schema not valid.');
|
||||
const promises = errors.map((error) =>
|
||||
context.logger.warn(formatErrorMessage({ error, components }))
|
||||
await Promise.all(
|
||||
errors.map((error) => context.logger.warn(formatErrorMessage({ error, components })))
|
||||
);
|
||||
await promises;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ async function updateServerPackageJson({ components, context }) {
|
||||
});
|
||||
}
|
||||
getPackages(components.types.actions);
|
||||
getPackages(components.types.auth.providers);
|
||||
getPackages(components.types.blocks);
|
||||
getPackages(components.types.connections);
|
||||
getPackages(components.types.requests);
|
||||
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
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 generateImportFile from './generateImportFile.js';
|
||||
|
||||
async function writeAuthImports({ components, context }) {
|
||||
await context.writeBuildArtifact(
|
||||
'plugins/auth/providers.js',
|
||||
generateImportFile({
|
||||
types: components.types.auth.providers,
|
||||
importPath: 'auth/providers',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
export default writeAuthImports;
|
@ -18,14 +18,14 @@ import generateImportFile from './generateImportFile.js';
|
||||
|
||||
async function writeOperatorImports({ components, context }) {
|
||||
await context.writeBuildArtifact(
|
||||
'plugins/operatorsClient.js',
|
||||
'plugins/operators/client.js',
|
||||
generateImportFile({
|
||||
types: components.types.operators.client,
|
||||
importPath: 'operators/client',
|
||||
})
|
||||
);
|
||||
await context.writeBuildArtifact(
|
||||
'plugins/operatorsServer.js',
|
||||
'plugins/operators/server.js',
|
||||
generateImportFile({
|
||||
types: components.types.operators.server,
|
||||
importPath: 'operators/server',
|
||||
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
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 writeActionImports from './writeActionImports.js';
|
||||
import writeAuthImports from './writeAuthImports.js';
|
||||
import writeBlockImports from './writeBlockImports.js';
|
||||
import writeConnectionImports from './writeConnectionImports.js';
|
||||
import writeIconImports from './writeIconImports.js';
|
||||
import writeOperatorImports from './writeOperatorImports.js';
|
||||
import writeStyleImports from './writeStyleImports.js';
|
||||
|
||||
async function writePluginImports({ components, context }) {
|
||||
await writeActionImports({ components, context });
|
||||
await writeAuthImports({ components, context });
|
||||
await writeBlockImports({ components, context });
|
||||
await writeConnectionImports({ components, context });
|
||||
await writeIconImports({ components, context });
|
||||
await writeOperatorImports({ components, context });
|
||||
await writeStyleImports({ components, context });
|
||||
}
|
||||
|
||||
export default writePluginImports;
|
@ -39,20 +39,15 @@ import testSchema from './build/testSchema.js';
|
||||
import validateApp from './build/validateApp.js';
|
||||
import validateConfig from './build/validateConfig.js';
|
||||
import updateServerPackageJson from './build/updateServerPackageJson.js';
|
||||
import writeActionImports from './build/writePluginImports/writeActionImports.js';
|
||||
import writeApp from './build/writeApp.js';
|
||||
import writeAuth from './build/writeAuth.js';
|
||||
import writeBlockImports from './build/writePluginImports/writeBlockImports.js';
|
||||
import writePluginImports from './build/writePluginImports/writePluginImports.js';
|
||||
import writeConfig from './build/writeConfig.js';
|
||||
import writeConnectionImports from './build/writePluginImports/writeConnectionImports.js';
|
||||
import writeConnections from './build/writeConnections.js';
|
||||
import writeGlobal from './build/writeGlobal.js';
|
||||
import writeIconImports from './build/writePluginImports/writeIconImports.js';
|
||||
import writeMenus from './build/writeMenus.js';
|
||||
import writeOperatorImports from './build/writePluginImports/writeOperatorImports.js';
|
||||
import writePages from './build/writePages.js';
|
||||
import writeRequests from './build/writeRequests.js';
|
||||
import writeStyleImports from './build/writePluginImports/writeStyleImports.js';
|
||||
import writeTypes from './build/writeTypes.js';
|
||||
|
||||
async function createContext({ customTypesMap, directories, logger, refResolver }) {
|
||||
@ -67,6 +62,9 @@ async function createContext({ customTypesMap, directories, logger, refResolver
|
||||
refResolver,
|
||||
typeCounters: {
|
||||
actions: createCounter(),
|
||||
auth: {
|
||||
providers: createCounter(),
|
||||
},
|
||||
blocks: createCounter(),
|
||||
connections: createCounter(),
|
||||
requests: createCounter(),
|
||||
@ -96,7 +94,6 @@ async function build(options) {
|
||||
await buildIcons({ components, context });
|
||||
await buildStyles({ components, context });
|
||||
await cleanBuildDirectory({ context });
|
||||
await writeActionImports({ components, context });
|
||||
await writeApp({ components, context });
|
||||
await writeAuth({ components, context });
|
||||
await writeConnections({ components, context });
|
||||
@ -106,11 +103,7 @@ async function build(options) {
|
||||
await writeGlobal({ components, context });
|
||||
await writeMenus({ components, context });
|
||||
await writeTypes({ components, context });
|
||||
await writeBlockImports({ components, context });
|
||||
await writeConnectionImports({ components, context });
|
||||
await writeOperatorImports({ components, context });
|
||||
await writeStyleImports({ components, context });
|
||||
await writeIconImports({ components, context });
|
||||
await writePluginImports({ components, context });
|
||||
await updateServerPackageJson({ components, context });
|
||||
await copyPublicFolder({ components, context });
|
||||
}
|
||||
|
@ -185,6 +185,37 @@ export default {
|
||||
},
|
||||
},
|
||||
},
|
||||
providers: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
required: ['id', 'type'],
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
errorMessage: {
|
||||
type: 'Auth provider "id" should be a string.',
|
||||
},
|
||||
},
|
||||
type: {
|
||||
type: 'string',
|
||||
errorMessage: {
|
||||
type: 'Auth provider "type" should be a string.',
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
type: 'object',
|
||||
},
|
||||
},
|
||||
errorMessage: {
|
||||
type: 'Auth provider should be an object.',
|
||||
required: {
|
||||
id: 'Auth provider should have required property "id".',
|
||||
type: 'Auth provider should have required property "type".',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
block: {
|
||||
@ -615,6 +646,9 @@ export default {
|
||||
app: {
|
||||
$ref: '#/definitions/app',
|
||||
},
|
||||
auth: {
|
||||
$ref: '#/definitions/authConfig',
|
||||
},
|
||||
cli: {
|
||||
type: 'object',
|
||||
errorMessage: {
|
||||
@ -628,9 +662,6 @@ export default {
|
||||
},
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
auth: {
|
||||
$ref: '#/definitions/authConfig',
|
||||
},
|
||||
basePath: {
|
||||
type: 'string',
|
||||
description: 'App base path to apply to all routes. Base path must start with "/".',
|
||||
|
Loading…
x
Reference in New Issue
Block a user