Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send registration confirmation email with verification link, remove u… #60

Merged
merged 8 commits into from
Sep 23, 2022
1 change: 1 addition & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,6 @@ [email protected]
## Seed values
# Tombolo Client ID - Give an ID, Example - 'tombolo_os',
TOMBOLO_CLIENT_ID=

# A user with admin privilege will be auto seeded. username is 'admin' password is what you specify below
ADMIN_PASSWORD=
39 changes: 20 additions & 19 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const withAuth = require('./middleware');
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');

var loginRouter = require('./routes/login');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var authRouter = require('./routes/auth');
var uiRouter = require('./routes/ui');
var appRouter = require('./routes/application');
var authV20Router = require('./routes/authv20');
var roleRouter = require('./routes/roles');
const withAuth = require('./middleware');
const loginRouter = require('./routes/login');
const usersRouter = require('./routes/users');
const authRouter = require('./routes/auth');
const uiRouter = require('./routes/ui');
const appRouter = require('./routes/application');
const authV20Router = require('./routes/authv20');
const roleRouter = require('./routes/roles');
const notificationRouter = require('./routes/notification')
const { userAccountCleanUp } = require("./jobSchedular");

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
//app.set('view engine', 'jade');

app.use(logger('dev'));
app.use(express.json());
Expand All @@ -32,12 +32,10 @@ app.use('/api/users', withAuth, usersRouter);
app.use('/api/auth/v20', authV20Router);
app.use('/api/auth', authRouter);
app.use('/admin', withAuth, uiRouter);
//app.use('/', withAuth, indexRouter);
app.use('/api/application', withAuth, appRouter);

app.use('/api/notification', notificationRouter)
app.use('/api/roles', withAuth, roleRouter)


// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
Expand All @@ -54,6 +52,9 @@ app.use(function(err, req, res, next) {
res.render('error');
});

app.listen(process.env["PORT"], '0.0.0.0', () => console.log('Server listening on port '+process.env["PORT"]));
app.listen(process.env["PORT"], '0.0.0.0', () => {
userAccountCleanUp();
console.log('Server listening on port '+process.env["PORT"])
});

module.exports = app;
76 changes: 47 additions & 29 deletions client/src/components/applications/ApplicationDetailsDialog.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import React, { useEffect } from 'react';
import { Modal, Form, Input, Select, InputNumber, message } from 'antd';
import React, { useEffect, useState } from 'react';
import { Modal, Form, Input, Select, InputNumber, message, Checkbox } from 'antd';

import { Constants } from '../common/Constants';
import { authHeader } from '../common/AuthHeader.js';

const Option = Select.Option;
const { TextArea } = Input;

function ApplicationDetailsDialog({ isShowing, onClose, selectedApplication, applications, setSelectedApplication }) {
function ApplicationDetailsDialog({ isShowing, onClose, selectedApplication, applications, notificationSettingsConfigured }) {
const [form] = Form.useForm();
const [selectedApplicationType, setSelectedApplicationType] = useState("");

//Use effect
useEffect(() => {
form.setFieldsValue(selectedApplication);
if (selectedApplication) {
form.setFieldsValue(selectedApplication);
setSelectedApplicationType(selectedApplication.applicationType);
}
// eslint-disable-next-line
}, [selectedApplication]);

Expand All @@ -26,8 +30,8 @@ function ApplicationDetailsDialog({ isShowing, onClose, selectedApplication, app
const saveApplication = async () => {
await form.validateFields();

if (applications.map((application) => application.name).includes(form.getFieldValue('name')) && !selectedApplication) {
message.error('Please pick a unique application name');
if (applications.map((application) => application.name).includes(form.getFieldValue("name")) && !selectedApplication) {
message.error("Please pick a unique application name");
return;
}

Expand All @@ -36,14 +40,14 @@ function ApplicationDetailsDialog({ isShowing, onClose, selectedApplication, app
if (selectedApplication) applicationDetails.id = selectedApplication.id;

try {
const response = await fetch('/api/application', {
method: selectedApplication ? 'put' : 'post', // put if editing
const response = await fetch("/api/application", {
method: selectedApplication ? "put" : "post", // put if editing
headers: authHeader(),
body: JSON.stringify(applicationDetails),
});

if (!response.ok) throw new Error('Unable to save application');
message.success('Application saved');
if (!response.ok) throw new Error("Unable to save application");
message.success("Application saved");
closeModal();
} catch (err) {
message.error(err.message);
Expand All @@ -57,31 +61,31 @@ function ApplicationDetailsDialog({ isShowing, onClose, selectedApplication, app
<Form.Item
label="Name"
name="name"
rules={[{ required: true, pattern: new RegExp(/^[a-zA-Z]{1}[a-zA-Z0-9 _-]*$/), message: 'Please enter a valid name!.' }]}
style={{ marginBottom: '5px' }}
rules={[{ required: true, pattern: new RegExp(/^[a-zA-Z]{1}[a-zA-Z0-9 _-]*$/), message: "Please enter a valid name!." }]}
style={{ marginBottom: "5px" }}
>
<Input name="name" placeholder="Name" />
</Form.Item>

<Form.Item
label="Application Type"
name="applicationType"
rules={[{ required: true, message: 'Please enter application type!' }]}
style={{ marginBottom: '5px' }}
rules={[{ required: true, message: "Please enter application type!" }]}
style={{ marginBottom: "5px" }}
>
<Select placeholder="Application Type">
<Select placeholder="Application Type" onChange={(value) => setSelectedApplicationType(value)}>
{Constants.APPLICATION_TYPES.map((applicationType) => (
<Option key={applicationType}>{applicationType}</Option>
))}
</Select>
</Form.Item>

<Form.Item style={{ marginBottom: '-10px' }}>
<Form.Item style={{ marginBottom: "-10px" }}>
<Form.Item
label="Client Id"
name="clientId"
rules={[{ required: true, pattern: new RegExp(/^[a-zA-Z]{1}[a-zA-Z0-9 _-]*$/), message: 'Please enter a valid client id!' }]}
style={{ display: 'inline-block', width: 'calc(60% - 8px)' }}
rules={[{ required: true, pattern: new RegExp(/^[a-zA-Z]{1}[a-zA-Z0-9 _-]*$/), message: "Please enter a valid client id!" }]}
style={{ display: "inline-block", width: "calc(60% - 8px)" }}
>
<Input name="clientId" placeholder="Client ID" />
</Form.Item>
Expand All @@ -91,23 +95,37 @@ function ApplicationDetailsDialog({ isShowing, onClose, selectedApplication, app
name="tokenTtl"
rules={[
{
type: 'number',
type: "number",
min: 300,
max: 3600,
message: 'Token TTL must be between 300 and 3600',
message: "Token TTL must be between 300 and 3600",
},
]}
style={{ display: 'inline-block', width: 'calc(40% - 8px)', marginLeft: '16px' }}
style={{ display: "inline-block", width: "calc(40% - 8px)", marginLeft: "16px" }}
>
<InputNumber name="tokenTtl" style={{ width: '100%' }} placeholder="Token TTL in minutes" />
<InputNumber name="tokenTtl" style={{ width: "100%" }} placeholder="Token TTL in minutes" />
</Form.Item>
</Form.Item>

{selectedApplicationType === "HPCC" || !selectedApplicationType || !notificationSettingsConfigured ? null : (
<Form.Item
name="registrationConfirmationRequired"
wrapperCol={{
offset: 0,
span: 16,
}}
valuePropName="checked"
style={{ marginBottom: "5px" }}
>
<Checkbox>Send registration confirmation</Checkbox>
</Form.Item>
)}

<Form.Item
label="Owner"
name="owner"
rules={[{ required: true, pattern: new RegExp(/^[a-zA-Z]{1}[a-zA-Z0-9 _-]*$/), message: 'Please enter a valid owner!' }]}
style={{ marginBottom: '5px' }}
rules={[{ required: true, pattern: new RegExp(/^[a-zA-Z]{1}[a-zA-Z0-9 _-]*$/), message: "Please enter a valid owner!" }]}
style={{ marginBottom: "5px" }}
>
<Input name="owner" placeholder="Owner" />
</Form.Item>
Expand All @@ -118,20 +136,20 @@ function ApplicationDetailsDialog({ isShowing, onClose, selectedApplication, app
required
rules={[
{
type: 'email',
message: 'The input is not valid E-mail!',
type: "email",
message: "The input is not valid E-mail!",
},
{
required: true,
message: 'Please input E-mail!',
message: "Please input E-mail!",
},
]}
style={{ marginBottom: '5px' }}
style={{ marginBottom: "5px" }}
>
<Input name="email" placeholder="E-mail" />
</Form.Item>

<Form.Item label="Description" name="description" style={{ marginBottom: '5px' }}>
<Form.Item label="Description" name="description" style={{ marginBottom: "5px" }}>
<TextArea rows={2} autoSize={{ minRows: 2 }} />
</Form.Item>
</Form>
Expand Down
Loading