Skip to content

Commit

Permalink
feat: Update dev server to work with logger.
Browse files Browse the repository at this point in the history
  • Loading branch information
SamTolmay committed Jun 22, 2023
1 parent fe46d23 commit f036a62
Show file tree
Hide file tree
Showing 29 changed files with 262 additions and 99 deletions.
2 changes: 1 addition & 1 deletion packages/api/src/routes/auth/events/createSignInEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ function createSignInEvent({ authConfig, logger, plugins }) {
type: 'signIn',
});

// TODO: Log provider
async function signInEvent({ account, isNewUser, profile, user }) {
logger.info({
event: 'auth_sign_in',
isNewUser,
provider: account?.provider,
user: {
id: user.id,
roles: user.roles,
Expand Down
15 changes: 10 additions & 5 deletions packages/api/src/routes/auth/events/createSignOutEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,16 @@ function createSignOutEvent({ authConfig, logger, plugins }) {
});

async function signOutEvent({ session, token }) {
console.log({ session, token });
// logger.info({
// event: 'auth_sign_out',
// user: session.user,
// });
const user = token?.user ?? session?.user;
logger.info({
event: 'auth_sign_out',
user: {
id: user.id,
roles: user.roles,
sub: user.sub,
session_id: user.session_id,
},
});
for (const plugin of signOutPlugins) {
await plugin.fn({
properties: plugin.properties ?? {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ import Page from './Page.js';
import setPageId from './setPageId.js';
import useRootConfig from './utils/useRootConfig.js';

import actions from '../build/plugins/actions.js';
import blocks from '../build/plugins/blocks.js';
import icons from '../build/plugins/icons.js';
import operators from '../build/plugins/operators/client.js';
import actions from '../../build/plugins/actions.js';
import blocks from '../../build/plugins/blocks.js';
import icons from '../../build/plugins/icons.js';
import operators from '../../build/plugins/operators/client.js';

const App = ({ auth, lowdefy }) => {
const router = useRouter();
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import React from 'react';
import AuthConfigured from './AuthConfigured.js';
import AuthNotConfigured from './AuthNotConfigured.js';

import authConfig from '../../build/auth.json';
import authConfig from '../../../build/auth.json';

function Auth({ children, session }) {
if (authConfig.configured === true) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import React, { useEffect, useRef } from 'react';
import { getSession, SessionProvider, signIn, signOut, useSession } from 'next-auth/react';

import lowdefyConfig from '../../build/config.json';
import lowdefyConfig from '../../../build/config.json';

function Session({ children }) {
const wasAuthenticated = useRef(false);
Expand Down
File renamed without changes.
File renamed without changes.
67 changes: 67 additions & 0 deletions packages/server-dev/lib/server/apiWrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
Copyright 2020-2023 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 path from 'path';
import crypto from 'crypto';
import { createApiContext } from '@lowdefy/api';
import { getSecretsFromEnv } from '@lowdefy/node-utils';

import config from '../../build/config.json';
import connections from '../../build/plugins/connections.js';
import createLogger from './log/createLogger.js';
import fileCache from './fileCache.js';
import getServerSession from './auth/getServerSession.js';
import logRequest from './log/logRequest.js';
import operators from '../../build/plugins/operators/server.js';
import getAuthOptions from './auth/getAuthOptions.js';

function apiWrapper(handler) {
return async function wrappedHandler(req, res) {
let logger = console;
try {
const rid = crypto.randomUUID();
logger = createLogger({ rid });
const authOptions = getAuthOptions({ logger });
const session = await getServerSession({ authOptions, req, res });
// Important to give absolute path so Next can trace build files
const context = createApiContext({
authOptions,
buildDirectory: path.join(process.cwd(), 'build'),
config,
connections,
fileCache,
headers: req.headers,
logger,
operators,
secrets: getSecretsFromEnv(),
session,
req,
});
logRequest({ context });
// Await here so that if handler throws it is caught.
const response = await handler({ context, req, res });
// TODO: Log response time?
return response;
} catch (error) {
// TODO: Improve (logError function)
// TODO: Log cause
logger.error(error);
// TODO: What we do here?
res.status(500).json({ name: error.name, message: error.message });
}
};
}

export default apiWrapper;
35 changes: 35 additions & 0 deletions packages/server-dev/lib/server/auth/getAuthOptions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
Copyright 2020-2023 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 { getNextAuthConfig } from '@lowdefy/api';
import { getSecretsFromEnv } from '@lowdefy/node-utils';

import adapters from '../../../build/plugins/auth/adapters.js';
import authJson from '../../../build/auth.json';
import callbacks from '../../../build/plugins/auth/callbacks.js';
import events from '../../../build/plugins/auth/events.js';
import providers from '../../../build/plugins/auth/providers.js';

function getAuthOptions({ logger }) {
return getNextAuthConfig({
authJson,
logger,
plugins: { adapters, callbacks, events, providers },
secrets: getSecretsFromEnv(),
});
}

export default getAuthOptions;
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
*/

import { getServerSession as getNextAuthServerSession } from 'next-auth/next';
import { authOptions } from '../../pages/api/auth/[...nextauth].js';
import authJson from '../../build/auth.json';

function getServerSession({ req, res }) {
import authJson from '../../../build/auth.json';

function getServerSession({ authOptions, req, res }) {
if (authJson.configured === true) {
return getNextAuthServerSession(req, res, authOptions);
}
Expand Down
File renamed without changes.
29 changes: 29 additions & 0 deletions packages/server-dev/lib/server/log/createLogger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
Copyright 2020-2023 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 pino from 'pino';

const logger = pino({
name: 'lowdefy_server',
level: process.env.LOWDEFY_LOG_LEVEL ?? 'info',
base: { pid: undefined, hostname: undefined },
});

function createLogger(metadata = {}) {
return logger.child(metadata);
}

export default createLogger;
76 changes: 76 additions & 0 deletions packages/server-dev/lib/server/log/logRequest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
Copyright 2020-2023 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.
*/

// TODO: Better name needed here maybe?
function logRequest({ context, metadata = {} }) {
const { user = {} } = context;
context.logger.debug({
// TODO:
// app_name
// app_version
// lowdefy_version
// build_hash
// config_hash
user: {
id: user.id,
roles: user.roles,
sub: user.sub,
session_id: user.session_id, // TODO: Implement session id
},
url: context.req.url,
method: context.req.method,
resolvedUrl: context.nextContext?.resolvedUrl,
hostname: context.req.hostname,
...metadata,
});
// TODO:
// Next local? nextContext.locale, nextContext.locales, nextContext.defaultLocale
// console.log('params', nextContext.params);
}

export default logRequest;

/*
User ID
Session ID
Event Type/Action
Timestamp
Source IP Address
User Agent
Resource ID/Identifier
Outcome/Status
Reason
Details/Additional Information
Targeted System
Page URL
Referrer URL
IP Address
Response Time
Error Messages
Device Information
Input Data
Behavioral Metrics
Error Level/Severity
Error Message
Error Code
HTTP Method
Stack Trace
Payload/Body
Application Version
Environment Information
*/
2 changes: 1 addition & 1 deletion packages/server-dev/pages/404.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
limitations under the License.
*/

import App from '../lib/App.js';
import App from '../lib/client/App.js';

export default App;
2 changes: 1 addition & 1 deletion packages/server-dev/pages/[pageId].js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
limitations under the License.
*/

import App from '../lib/App.js';
import App from '../lib/client/App.js';

export default App;
2 changes: 1 addition & 1 deletion packages/server-dev/pages/_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import React, { Suspense, useRef } from 'react';
import dynamic from 'next/dynamic';

import Auth from '../lib/auth/Auth.js';
import Auth from '../lib/client/auth/Auth.js';

// Must be in _app due to next specifications.
import '../build/plugins/styles.less';
Expand Down
25 changes: 6 additions & 19 deletions packages/server-dev/pages/api/auth/[...nextauth].js
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,23 @@
*/

import NextAuth from 'next-auth';
import { createApiContext, getNextAuthConfig } from '@lowdefy/api';

import apiWrapper from '../../../lib/server/apiWrapper.js';
import authJson from '../../../build/auth.json';
import config from '../../../build/config.json';
import adapters from '../../../build/plugins/auth/adapters.js';
import callbacks from '../../../build/plugins/auth/callbacks.js';
import events from '../../../build/plugins/auth/events.js';
import fileCache from '../../../lib/fileCache.js';
import providers from '../../../build/plugins/auth/providers.js';

export const authOptions = getNextAuthConfig(
createApiContext({
config,
fileCache,
logger: console,
}),
{ authJson, plugins: { adapters, callbacks, events, providers } }
);

export default async function auth(req, res) {

async function handler({ context, req, res }) {
if (authJson.configured === true) {
// Required for emails in corporate networks, see:
// https://next-auth.js.org/tutorials/avoid-corporate-link-checking-email-provider
if (req.method === 'HEAD') {
return res.status(200).end();
}
return await NextAuth(req, res, authOptions);
return await NextAuth(req, res, context.authOptions);
}

return res.status(404).json({
message: 'Auth not configured',
});
}

export default apiWrapper(handler);
22 changes: 7 additions & 15 deletions packages/server-dev/pages/api/page/[pageId].js
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,19 @@
limitations under the License.
*/

import { createApiContext, getPageConfig } from '@lowdefy/api';
import { getPageConfig } from '@lowdefy/api';

import config from '../../../build/config.json';
import fileCache from '../../../lib/fileCache.js';
import getServerSession from '../../../lib/auth/getServerSession.js';

export default async function handler(req, res) {
const session = await getServerSession({ req, res });
const apiContext = createApiContext({
buildDirectory: './build',
config,
fileCache,
logger: console,
session,
});
import apiWrapper from '../../../lib/server/apiWrapper.js';

async function handler({ context, req, res }) {
const { pageId } = req.query;
const pageConfig = await getPageConfig(apiContext, { pageId });
const pageConfig = await getPageConfig(context, { pageId });
// TODO: Do we log here?
if (pageConfig === null) {
res.status(404).send('Page not found.');
} else {
res.status(200).json(pageConfig);
}
}

export default apiWrapper(handler);

0 comments on commit f036a62

Please sign in to comment.