### Instruction:
Create a full-stack JavaScript application that visualizes data from a public API (e.g., weather, stocks, etc.) using D3.js for the frontend and Express.js for the backend. The application should include user authentication and the ability to save custom visualizations to a MongoDB database.
PLAINFORMAT

### Response:

// app.js
const express = require('express');
const bodyParser = require('body-parser');
const session = require('express-session');
const flash = require('connect-flash');
const passport = require('passport');

const app = express();

// Passport config
require('./config/passport')(passport);

// EJS setup
app.set('view engine', 'ejs');

// Body parser middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// Session middleware
app.use(session({
  secret: 'secret',
  resave: true,
  saveUninitialized: true
}));

// Passport middleware
app.use(passport.initialize());
app.use(passport.session());

// Connect flash middleware
app.use(flash());

// Global variables for flash messages
app.use((req, res, next) => {
  res.locals.success_msg = req.flash('success_msg');
  res.locals.error_msg = req.flash('error_msg');
  res.locals.error = req.flash('error');
  next();
});

// Routes
app.use('/', require('./routes/index'));
app.use('/users', require('./routes/users'));

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));

// db.js
const mongoose = require('mongoose');

const connectDB = async () => {
  try {
    await mongoose.connect('mongodb://localhost/d3-visualization-app', {
      useNewUrlParser: true,
      useUnifiedTopology: true
    });
    console.log('MongoDB connected...');
  } catch (err) {
    console.error(err.message);
    process.exit(1);
  }
};

module.exports = connectDB;

// User.js
const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true
  },
  password: {
    type: String,
    required: true
  },
  date: {
    type: Date,
    default: Date.now
  }
});

const User = mongoose.model('User', UserSchema);

module.exports = User;

// Visualization.js
const mongoose = require('mongoose');

const VisualizationSchema = new mongoose.Schema({
  user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User'
  },
  title: {
    type: String,
    required: true
  },
  dataUrl: {
    type: String,
    required: true
  },
  chartType: {
    type: String,
    required: true
  },
  date: {
    type: Date,
    default: Date.now
  }
});

const Visualization = mongoose.model('Visualization', VisualizationSchema);

module.exports = Visualization;

// index.js (routes)
const express = require('express');
const router = express.Router();
const { ensureAuthenticated } = require('../config/auth');

router.get('/', (req, res) => res.render('welcome'));

router.get('/dashboard', ensureAuthenticated, (req, res) =>
  res.render('dashboard', {
    user: req.user
  })
);

module.exports = router;

// users.js (routes)
// ... import necessary packages and models ...

const router = express.Router();

// Register page
router.get('/register', (req, res) => res.render('register'));

// Login page
router.get('/login', (req, res) => res.render('login'));

// Register handle
router.post('/register', (req, res) => {
  // ... handle user registration ...
});

// Login handle
router.post('/login', (req, res, next) => {
  passport.authenticate('local', {
    successRedirect: '/dashboard',
    failureRedirect: '/users/login',
    failureFlash: true
  })(req, res, next);
});

// Logout handle
router.get('/logout', (req, res) => {
  req.logout();
  req.flash('success_msg', 'You are logged out');
  res.redirect('/users/login');
});

module.exports = router;

// main.js (D3 visualization)
d3.json('https://api.example.com/data')
  .then(data => {
    // Create visualization using D3.js
  })
  .catch(error => console.error(error));