@lowdefy/server 4.0.0-rc.9 → 4.5.0

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/pages/_app.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2023 Lowdefy, Inc
2
+ Copyright 2020-2024 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -13,29 +13,37 @@
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  */
16
- /* eslint-disable react/jsx-props-no-spreading */
17
16
 
18
17
  import React, { useRef } from 'react';
19
18
  import dynamic from 'next/dynamic';
20
19
 
21
- import Auth from '../lib/auth/Auth.js';
20
+ import { ErrorBoundary } from '@lowdefy/block-utils';
21
+
22
+ import Auth from '../lib/client/auth/Auth.js';
23
+ import createLogUsage from '../lib/client/createLogUsage.js';
22
24
 
23
25
  // Must be in _app due to next specifications.
24
26
  import '../build/plugins/styles.less';
25
27
 
26
28
  function App({ Component, pageProps: { session, rootConfig, pageConfig } }) {
27
- const lowdefyRef = useRef({});
29
+ const usageDataRef = useRef({});
30
+ const lowdefyRef = useRef({ eventCallback: createLogUsage({ usageDataRef }) });
28
31
  return (
29
- <Auth session={session}>
30
- {(auth) => (
31
- <Component
32
- auth={auth}
33
- lowdefy={lowdefyRef.current}
34
- rootConfig={rootConfig}
35
- pageConfig={pageConfig}
36
- />
37
- )}
38
- </Auth>
32
+ <ErrorBoundary fullPage>
33
+ <Auth session={session}>
34
+ {(auth) => {
35
+ usageDataRef.current.user = auth.session?.hashed_id;
36
+ return (
37
+ <Component
38
+ auth={auth}
39
+ lowdefy={lowdefyRef.current}
40
+ rootConfig={rootConfig}
41
+ pageConfig={pageConfig}
42
+ />
43
+ );
44
+ }}
45
+ </Auth>
46
+ </ErrorBoundary>
39
47
  );
40
48
  }
41
49
 
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2023 Lowdefy, Inc
2
+ Copyright 2020-2024 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2023 Lowdefy, Inc
2
+ Copyright 2020-2024 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -15,36 +15,23 @@
15
15
  */
16
16
 
17
17
  import NextAuth from 'next-auth';
18
- import { createApiContext, getNextAuthConfig } from '@lowdefy/api';
19
18
 
20
- import adapters from '../../../build/plugins/auth/adapters.js';
19
+ import apiWrapper from '../../../lib/server/apiWrapper.js';
21
20
  import authJson from '../../../build/auth.json';
22
- import callbacks from '../../../build/plugins/auth/callbacks.js';
23
- import config from '../../../build/config.json';
24
- import events from '../../../build/plugins/auth/events.js';
25
- import fileCache from '../../../lib/fileCache.js';
26
- import providers from '../../../build/plugins/auth/providers.js';
27
-
28
- export const authOptions = getNextAuthConfig(
29
- createApiContext({
30
- config,
31
- fileCache,
32
- logger: console,
33
- }),
34
- { authJson, plugins: { adapters, callbacks, events, providers } }
35
- );
36
-
37
- export default async function auth(req, res) {
38
- if (authJson.configured === true) {
39
- // Required for emails in corporate networks, see:
40
- // https://next-auth.js.org/tutorials/avoid-corporate-link-checking-email-provider
41
- if (req.method === 'HEAD') {
42
- return res.status(200).end();
43
- }
44
- return await NextAuth(req, res, authOptions);
21
+
22
+ async function handler({ context, req, res }) {
23
+ if (authJson.configured !== true) {
24
+ return res.status(404).json({
25
+ message: 'Auth not configured',
26
+ });
45
27
  }
46
28
 
47
- return res.status(404).json({
48
- message: 'Auth not configured',
49
- });
29
+ // Required for emails in corporate networks, see:
30
+ // https://next-auth.js.org/tutorials/avoid-corporate-link-checking-email-provider
31
+ if (req.method === 'HEAD') {
32
+ return res.status(200).end();
33
+ }
34
+ return NextAuth(req, res, context.authOptions);
50
35
  }
36
+
37
+ export default apiWrapper(handler);
@@ -0,0 +1,32 @@
1
+ /*
2
+ Copyright 2020-2024 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+ import { callEndpoint } from '@lowdefy/api';
18
+
19
+ import apiWrapper from '../../../lib/server/apiWrapper.js';
20
+
21
+ async function handler({ context, req, res }) {
22
+ if (req.method !== 'POST') {
23
+ throw new Error('Only POST requests are supported.');
24
+ }
25
+ const { endpointId } = req.query;
26
+ const { blockId, payload, pageId } = req.body;
27
+ context.logger.info({ event: 'call_api_endpoint', blockId, endpointId, pageId });
28
+ const response = await callEndpoint(context, { blockId, endpointId, pageId, payload });
29
+ res.status(200).json(response);
30
+ }
31
+
32
+ export default apiWrapper(handler);
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2023 Lowdefy, Inc
2
+ Copyright 2020-2024 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -14,40 +14,19 @@
14
14
  limitations under the License.
15
15
  */
16
16
 
17
- import path from 'path';
18
- import { callRequest, createApiContext } from '@lowdefy/api';
19
- import { getSecretsFromEnv } from '@lowdefy/node-utils';
17
+ import { callRequest } from '@lowdefy/api';
20
18
 
21
- import config from '../../../../build/config.json';
22
- import connections from '../../../../build/plugins/connections.js';
23
- import getServerSession from '../../../../lib/auth/getServerSession.js';
24
- import operators from '../../../../build/plugins/operators/server.js';
25
- import fileCache from '../../../../lib/fileCache.js';
19
+ import apiWrapper from '../../../../lib/server/apiWrapper.js';
26
20
 
27
- export default async function handler(req, res) {
28
- try {
29
- if (req.method !== 'POST') {
30
- throw new Error('Only POST requests are supported.');
31
- }
32
- const session = await getServerSession({ req, res });
33
- // Important to give absolute path so Next can trace build files
34
- const apiContext = createApiContext({
35
- buildDirectory: path.join(process.cwd(), 'build'),
36
- config,
37
- connections,
38
- fileCache,
39
- // logger: console,
40
- logger: { debug: () => {} },
41
- operators,
42
- secrets: getSecretsFromEnv(),
43
- session,
44
- });
45
-
46
- const { blockId, pageId, requestId } = req.query;
47
- const { payload } = req.body;
48
- const response = await callRequest(apiContext, { blockId, pageId, payload, requestId });
49
- res.status(200).json(response);
50
- } catch (error) {
51
- res.status(500).json({ name: error.name, message: error.message });
21
+ async function handler({ context, req, res }) {
22
+ if (req.method !== 'POST') {
23
+ throw new Error('Only POST requests are supported.');
52
24
  }
25
+ const { pageId, requestId } = req.query;
26
+ const { blockId, payload } = req.body;
27
+ context.logger.info({ event: 'call_request', pageId, requestId, blockId });
28
+ const response = await callRequest(context, { blockId, pageId, payload, requestId });
29
+ res.status(200).json(response);
53
30
  }
31
+
32
+ export default apiWrapper(handler);
@@ -0,0 +1,68 @@
1
+ /*
2
+ Copyright 2020-2024 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+ // TODO
18
+ // import crypto from 'crypto';
19
+
20
+ import appJson from '../../build/app.json';
21
+ import packageJson from '../../package.json';
22
+ import apiWrapper from '../../lib/server/apiWrapper.js';
23
+ // import validateLicense from '../../lib/server/validateLicense.js';
24
+
25
+ async function handler({ context, req, res }) {
26
+ if (req.method !== 'POST') {
27
+ throw new Error('Only POST requests are supported.');
28
+ }
29
+ const { user, machine } = req.body;
30
+ const host = req.headers.host;
31
+ context.logger.info({ event: 'log_usage', user, machine });
32
+
33
+ // const license = await validateLicense();
34
+ // if (license.entitlements.includes['OFFLINE']) {
35
+ // return res.status(200).json({ offline: true });
36
+ // }
37
+ const timestamp = Date.now();
38
+
39
+ // const data = [
40
+ // `git_sha: ${appJson.git_sha}`,
41
+ // `host: ${host}`,
42
+ // `license_key: ${license.id}`,
43
+ // `machine: ${machine}`,
44
+ // `timestamp: ${timestamp}`,
45
+ // `user: ${user}`,
46
+ // `version: ${packageJson.version}`,
47
+ // ].join('\n');
48
+
49
+ // const hmac = crypto.createHmac('sha256', process.env.LOWDEFY_LICENSE_KEY ?? 'NO_LICENSE');
50
+ // hmac.update(data);
51
+ // const sig = hmac.digest('base64');
52
+
53
+ return res.status(200).json({
54
+ offline: false,
55
+ data: {
56
+ git_sha: appJson.git_sha,
57
+ host,
58
+ // license_key: license.id,
59
+ machine,
60
+ // sig,
61
+ timestamp,
62
+ user,
63
+ version: packageJson.version,
64
+ },
65
+ });
66
+ }
67
+
68
+ export default apiWrapper(handler);
package/pages/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020-2023 Lowdefy, Inc
2
+ Copyright 2020-2024 Lowdefy, Inc
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -14,28 +14,17 @@
14
14
  limitations under the License.
15
15
  */
16
16
 
17
- import path from 'path';
18
- import { createApiContext, getPageConfig, getRootConfig } from '@lowdefy/api';
17
+ import { getPageConfig, getRootConfig } from '@lowdefy/api';
19
18
 
20
- import config from '../build/config.json';
21
- import fileCache from '../lib/fileCache.js';
22
- import getServerSession from '../lib/auth/getServerSession.js';
23
- import Page from '../lib/Page.js';
19
+ import serverSidePropsWrapper from '../lib/server/serverSidePropsWrapper.js';
20
+ import Page from '../lib/client/Page.js';
24
21
 
25
- export async function getServerSideProps(context) {
26
- const session = await getServerSession(context);
27
-
28
- // Important to give absolute path so Next can trace build files
29
- const apiContext = createApiContext({
30
- buildDirectory: path.join(process.cwd(), 'build'),
31
- config,
32
- fileCache,
33
- logger: console,
34
- session,
35
- });
36
- const rootConfig = await getRootConfig(apiContext);
22
+ async function getServerSidePropsHandler({ context }) {
23
+ const rootConfig = await getRootConfig(context);
37
24
  const { home } = rootConfig;
25
+ const { logger, session } = context;
38
26
  if (home.configured === false) {
27
+ logger.info({ event: 'redirect_to_homepage', pageId: home.pageId });
39
28
  return {
40
29
  redirect: {
41
30
  destination: `/${home.pageId}`,
@@ -43,8 +32,9 @@ export async function getServerSideProps(context) {
43
32
  },
44
33
  };
45
34
  }
46
- const pageConfig = await getPageConfig(apiContext, { pageId: home.pageId });
35
+ const pageConfig = await getPageConfig(context, { pageId: home.pageId });
47
36
  if (!pageConfig) {
37
+ logger.info({ event: 'redirect_page_not_found', pageId: home.pageId });
48
38
  return {
49
39
  redirect: {
50
40
  destination: '/404',
@@ -52,6 +42,7 @@ export async function getServerSideProps(context) {
52
42
  },
53
43
  };
54
44
  }
45
+ logger.info({ event: 'page_view', pageId: home.pageId });
55
46
  return {
56
47
  props: {
57
48
  pageConfig,
@@ -61,4 +52,6 @@ export async function getServerSideProps(context) {
61
52
  };
62
53
  }
63
54
 
55
+ export const getServerSideProps = serverSidePropsWrapper(getServerSidePropsHandler);
56
+
64
57
  export default Page;