{% extends '../../base.html.twig' %}

{% block body %}
  <div class="container-fluid">
    <div class="row flex-xl-nowrap">
      {% include '../../../documentation/navbar.html.twig' with {
        'route' : nodefony.route
      } %}
      <main class="col-12 col-md-9 col-xl-8 py-md-3 pl-md-5" style="top: 5rem;">

        <div class="page-header">
          <h1>Application Configurations</h1>
          <p>
            Bundle Application is a special bundle in app directory you can find a 'config' directory
            <br>

            <h2 >
              You can see here :</h2>

            <p>
              <ul>
                <li>
                  <a href="#global_application">Goblal Configuration</a>
                </li>
                <li>
                  <a href="#routing_application">Routing Configuration</a>
                </li>
                <li>
                  <a href="#firewall_application">Firewall Configuration</a>
                </li>
                <li>
                  <a href="#webpack">Webpack Configurations</a>
                </li>
                <li>
                  <a href="#override">Override Configuration</a>
                </li>
              </ul>
              <p>

                <p></div>

                <h2>Location configurations in File System
                  <span class="badge">Directory</span></h2>
                <div class="doc2">
                  Location :
                  <code>./app/config</code>
                  <pre><code class="hljs console" >
        $ ls -l ./app/config
        total 48
        -rw-r--r--  1 cci  staff  5952 15 nov 11:35 config.js
        -rw-r--r--  1 cci  staff   138 23 oct 09:51 routing.js
        -rw-r--r--  1 cci  staff   411  2 nov 09:41 security.js
        -rw-r--r--  1 cci  staff    21 14 nov 18:20 services.js
        drwxr-xr-x  4 cci  staff   136  2 nov 09:41 webpack
        -rw-r--r--  1 cci  staff  2140  2 nov 09:41 webpack.config.js

        app/config/
        ├── config.js
        ├── routing.js
        ├── security.js
        ├── services.js
        ├── webpack
        │   ├── webpack.dev.config.js
        │   └── webpack.prod.config.js
        └── webpack.config.js

        </code></pre>
                </div>

                <h2 id="global_application">Goblal Configuration
                  <span class="badge">File</span>
                </h2>

                <div class="doc2">

                  <div class="card">
                    <!-- Default card contents -->
                    <div class="card-header">
                      Application Global Configuration
                    </div>
                    <div class="card-body">

                      <div class="doc3">
                        <div class="alert alert-info" role="alert">
                          Application is a Bundle with special comportement
                          <br>
                          This file override configuration of multiple Third-Party Bundles
                        </div>
                      </div>

                      Location :
                      <code>./app/config/config.js</code>
                      <pre><code class="hljs javascript" >
        /**
         *  NODEFONY APP CONFIG
         *
         *   @here You can OVERRIDE all Bundles Configurations
         */
        const path = require("path");

        module.exports = {
          locale: "en_en",
          App: {
            projectYear: 2019,
            locale: "en_en",
            authorName: "admin",
            authorMail: "admin@nodefony.com",
          },
          lang: {
            en_en: "english",
            fr_fr: "français"
          },
          /**
           *    WATCHERS
           *
           *  watchers Listen to changes, deletion, renaming of files and directories
           *  of different components
           *
           *  For watch all components
           *      watch:                    true
           *  or
           *      watch:{
           *        controller:             true
           *        config:                 true        // only  routing.js
           *        views:                  true
           *        translations:           true
           *        webpack:                true
           *      }
           *
           */
          watch: false,

          /**
           *    OVERRIDE MONITORING BUNDLE
           *
           *    see MONITORING BUNDLE config for more options
           *
           */
          "monitoring-bundle": {
            debugBar: true,
            forceDebugBarProd: false,
            profiler: {
              active: false,
              storage: "orm"
            }
          },

          /**
           *    OVERRIDE FRAMEWORK Bundle
           *
           *    see FRAMEWORK BUNDLE config for more options
           *
           */
          "framework-bundle": {
            webpack: {
              cache: true,
              outputFileSystem: "file-system" // memory-fs not implemented yet
            },
            stats: {
              colors: true,
              verbose: true,
              maxModules: 16 // Infinity
            }
          },

          /**
           *  OVERRIDE MAIL Bundle
           *
           *   @see FRAMEWORK MAIL config for more options
           *     https://nodemailer.com
           *
           *   @examples :   gmail
           *    https://myaccount.google.com/security
           *
           *    nodemailer :{
           *      default : "gmail",
           *      transporters :{
           *        gmail : {
           *          host: "smtp.gmail.com",
           *          port: 465,
           *          secure: true, // true for 465, false for other ports
           *          auth: {
           *            user: "user@gmail.com",
           *            pass: "xxxxxxxxx"
           *          },
           *          tls: {
           *            // do not fail on invalid certs
           *            rejectUnauthorized: false
           *          }
           *        }
           *      }
           *    }
           */
          "mail-bundle": {
            nodemailer: {
              default: null,
              transporters: {
                /*free: {
                  host: "smtp.free.fr",
                  port: 465,
                  secure: true, // true for 465, false for other ports
                  auth: {
                    user: "", // generated  user
                    pass: "" // generated  password
                  }
                }*/
              }
            }
          },

          /**
           *  OVERRIDE ORM SEQUELIZE BUNDLE
           *
           *       @see SEQUELIZE BUNDLE config for more options
           *       @more options http://docs.sequelizejs.com/class/lib/sequelize.js~Sequelize.html
           *
           *       Nodefony Database Management
           *        dialect :               'mysql'|'sqlite'|'postgres'|'mssql'
           *
           *       By default nodefony create  connector name nodefony ( driver sqlite )
           *       for manage Sessions / Users
           *
           *       For mysql/mariadb create database nodefony before
           *       Mysql > CREATE DATABASE nodefony;
           *
           *       Here create new databases connectors
           *       and use for sync connectors :
           *       nodefony sequelize:sync
           */
          "sequelize-bundle": {
            debug: false,
            connectors: {
              /*nodefony: {
                driver: "mysql",
                dbname: 'nodefony',
                username: 'nodefony',
                password: 'nodefony',
                options: {
                  dialect: "mysql",
                  host: "localhost",
                  port: "3306",
                  pool:{
                    max: 5,
                    min: 0,
                    idle: 10000,
                    acquire: 60000
                  }
                }
              }*/
            }
          },

          /**
           *   OVERRIDE ORM BUNDLE MONGOOSE
           *
           *       @see MONGO BUNDLE config for more options
           *       @more options https://mongoosejs.com/docs/connections.html
           *
           *
           *       By default nodefony create  connector name nodefony
           *       for manage Sessions / Users
           */
          "mongoose-bundle": {
            debug: false,
            connectors: {
              nodefony: {
                host: "localhost",
                port: 27017,
                dbname: "nodefony",
                settings: {
                  user: "",
                  pass: "",
                  authSource: "admin",
                  reconnectTries: 100,
                  reconnectInterval: 5000,
                  autoReconnect: true,
                  poolSize: 5
                }
              }
            }
          },

          /**
           *  OVERRIDE BUNDLE HTTP SETTINGS
           *
           *       see HTTP BUNDLE config for more options
           *
           *       query string parser
           *       form-data multipart parser
           *       upload
           *       statics files
           *       session
           *       http server
           *       https server
           *       upload
           *       websocket server
           *       websocket secure server
           *       sockjs dev server ( webpack dev server like WDS)
           *
           */
          "http-bundle": {
            // For more options request parser formidable @see : https://github.com/felixge/node-formidable
            request: {
              uploadDir: "/tmp", // temporing file upload system
              maxFileSize: 2097152, // In Bytes
              maxFieldsSize: 2097152, // 2MB
              maxFields: 1000, // 0 for unlimited
            },
            //For more options queryString parser QS @see : https://github.com/ljharb/qs
            queryString: {
              parameterLimit: 1000,
              delimiter: "&"
            },
            //Server @see :                https://nodejs.org/dist/latest-v8.x/docs/api/http.html*http_class_http_server
            http: {
              responseTimeout: 40000,
              headers: {
                "Cache-Control": "private, no-store, max-age=0, no-cache, must-revalidate"
              }
            },
            https: {
              responseTimeout: 40000,
              headers: {
                "Cache-Control": "private, no-store, max-age=0, no-cache, must-revalidate"
              }
            },
            http2: {
              enablePush: true
            },
            statics: {
              defaultOptions: {
                cacheControl: true,
                maxAge: 0
              },
              web: {
                path: "web",
                options: {
                  maxAge: 0 //30*24*60*60*1000
                }
              }
            },
            session: {
              start: false, // false || true || Name Session Context
              name: "nodefony",
              handler: "orm", // files | orm | memcached    => "nodefony.session.storage"
              //save_path: "./tmp/sessions", // for session.storage.files only
              use_strict_mode: true,
              gc_probability: 1,
              gc_divisor: 100,
              gc_maxlifetime: 1440,
              use_cookies: true,
              use_only_cookies: true,
              referer_check: false,
              cookie: {
                maxAge: 0, // like cookie_lifetime php  => secondes or ms style ('1d', "1h")
                secure: false, // Set true for https site only see https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Set-Cookie
                httpOnly: true
              },
              memcached: {
                servers: {
                  nodefony: {
                    location: "127.0.0.1",
                    port: 11211,
                    weight: 1
                  }
                }
              }
            }
          },

          /**
           *    OVERRIDE REDIS BUNDLE SETTINGS
           *
           *   All Options :                https://github.com/NodeRedis/node_redis
           *
           *   Add clients connections
           *   connections :{
           *     data :{
           *       name: "data"
           *      },
           *     publish :{
           *       name: "publish"
           *      },
           *     subscribe :{
           *       name: "subscribe"
           *      }
           *    }
           */
          "redis-bundle": {
            redis: {
              debug: true,
              globalOptions: {
                host: "localhost",
                port: 6379,
                family: "IPv4",
                disable_resubscribing: false,
                tls: null,
                no_ready_check: false,
                socket_keepalive: false,
                return_buffers: false,
                retry_unfulfilled_commands: true
              },
              connections: {
                main: {
                  name: "main"
                }
              }
            }
          },

          /**
           * OVERRIDE ELASTIC BUNDLE SETTINGS
           *   elasticsearch
           *
           *	 options  :  https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/configuration.html
           *
           */
          "elastic-bundle": {
            elasticsearch: {
              globalHostsOptions: {
                protocol: "http"
              },
              globalOptions: {
                ssl: {
                  //key : path.resolve("config","certificates","server","privkey.pem"),
                  //cert : path.resolve("config","certificates","server","cert.pem"),
                  //ca : path.resolve("config","certificates","ca","nodefony-root-ca.crt.pem")
                }
              },
              connections: {
                main: {
                  hosts: [{
                    host: "localhost",
                    port: 9200
                  }],
                  sniffOnStart: true,
                  sniffInterval: 5000
                }
              }
            }
          },

          /**
           *  OVERRIDE SECURITY BUNDLE
           *
           *   HEADERS SECURITY
           *
           *    Content-Security-Policy
           *    Strict-Transport-Security
           *     ...
           *    Manage and Clean hsts in chrome
           *     chrome://net-internals/*hsts
           */
          "security-bundle": {
            headers: {
              http: {
                //"Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",
                "X-Frame-Options": "SAMEORIGIN",
                "X-Content-Type-Options": "nosniff"
              },
              https: {
                //"Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",
                "X-Frame-Options": "SAMEORIGIN",
                "X-Content-Type-Options": "nosniff"
              }
            }
          },

          /**
           *  OVERRIDE BUNDLE REALTIME
           *
           *       see REALTIME BUNDLE config for more options
           *       monitoring service realtime
           */
          "realtime-bundle": {
            services: {
              monitoring: {
                type: "tcp",
                port: 1318,
                domain: "0.0.0.0"
              }
            }
          }
        };
        	            </code></pre>
                    </div>

                    <table class="table">
                      <thead>
                        <th class="config-parameters">Parameters</th>
                        <th>Description</th>
                        <th>Data Type</th>
                        <th>Example /
                          <span class="badge">Default</span>
                        </th>
                      </thead>
                      <tbody>
                        <tr>
                          <td class="config-parameters">name</td>
                          <td>Bundle Name</td>
                          <td>String</td>
                          <td>AppBundle</td>
                        </tr>
                        <tr>
                          <td class="config-parameters">version</td>
                          <td>Bundle Version
                          </td>
                          <td>String</td>
                          <td>1.0</td>
                        </tr>
                        <tr>
                          <td class="config-parameters">locale</td>
                          <td>I18n Bundle locale</td>
                          <td>String</td>
                          <td>en_en</td>
                        </tr>

                        <tr>
                          <td class="config-parameters">App.projectName</td>
                          <td>
                            Name of Application (project)
                          </td>
                          <td>String</td>
                          <td></span></td>
                      </tr>
                      <tr>
                        <td class="config-parameters">App.projectYear</td>
                        <td>
                          Year Application
                        </td>
                        <td>String</td>
                        <td></td>
                      </tr>
                      <tr>
                        <td class="config-parameters">App.authorName</td>
                        <td>Author
                        </td>
                        <td>String</td>
                        <td></td>
                      </tr>
                      <tr>
                        <td class="config-parameters">App.authorMail</td>
                        <td>
                          Author email
                        </td>
                        <td>String</td>
                        <td></td>
                      </tr>
                      <tr>
                        <td class="config-parameters">lang</td>
                        <td>
                          All langs enable in Application
                        </td>
                        <td>Object</td>
                        <td></td>
                      </tr>

                    </tbody>
                  </table>
                </div>
              </div>
              <br>
              <h2 id="routing_application">Application Routing Configuration
                <span class="badge">File</span>
              </h2>
              <div class="doc2">
                <div class="card card-default">
                  <!-- Default card contents -->
                  <div class="card-header">
                    Application Routing Configuration
                  </div>
                  <div class="card-body">
                    <p>Location :
                      <code>./app/config/routing.js</code>
                    </p>
                    <pre><code class="hljs javascript" >
        module.exports = {
          // home
          home: {
            pattern: "/",
            defaults: {
              controller: "app:app:index"
            }
          }
        };
        	  </code></pre>
                  </div>
                </div>
              </div>
              <br>
              <h2 id="firewall_application">Application Firewall Configuration
                <span class="badge">File</span>
              </h2>

              <div class="doc2">
                <div class="card card-default">
                  <!-- Default card contents -->
                  <div class="card-header">
                    Application Firewall Configuration
                  </div>
                  <div class="card-body">
                    <p>Location :
                      <code>./app/config/security.js</code>
                    </p>
                    <pre><code class="hljs javascript">/**
         *  Firewall Config  service Security
         */
        module.exports = {

          security: {
            /**
             *  FIREWALL strategy
             *  when change security context (usefull with multi firewalls areas)
             *
             *  Strategy can be : none, migrate, invalidate
             */
            session_fixation_strategy: "migrate",

            /**
             *  FIREWALL  PROVIDER
             */
            providers: {
              anonymous: {
                anonymous: {
                  provider: "anonymous"
                }
              },
              nodefony: {
                entity: {
                  name: "user",
                  property: "username"
                }
              }
            },
            encoders: {
              user: {
                algorithm: "bcrypt",
                saltRounds: 13
              }
            },

            /**
             *  FIREWALL  Authorization
             */
            access_control: [{
              path: /^\/nodefony/,
              roles: ["ROLE_MONITORING"],
              requires_channel: "https",
              allow_if: {
                roles: ["ROLE_ADMIN"]
              }
            }],

            /**
             * FIREWALL  AREAS
             */
            firewalls: {
              // SECURITY AREA MONITORING  <passport-local>
              nodefony_area: {
                pattern: /^\/nodefony/,
                provider: "nodefony",
                form_login: {
                  login_path: "/login/nodefony",
                  check_path: "/login/check",
                  default_target_path: "/"
                },
                "passport-local": {
                  usernameField: 'username',
                  passwordField: 'passwd'
                },
                logout: "/logout",
                context: null,
                redirectHttps: true
              }
            }
          }
        };
        	  </code></pre>
                  </div>
                </div>
              </div>
              <br>
              <h2 id="webpack">Webpack Configurations</h2>

              <div class="doc2">
                <div class="card card-default">
                  <!-- Default card contents -->
                  <div class="card-header">
                    Bundle Webpack Configuration
                  </div>
                  <div class="card-body">
                    <p>Location :
                      <code>./app/config/webpack.config.js</code>
                    </p>
                    <pre><code class="hljs javascript">const path = require("path");
        //const webpack = require('webpack');
        const MiniCssExtractPlugin = require("mini-css-extract-plugin");
        const webpackMerge = require('webpack-merge');

        // Default context <bundle base directory>
        //const context = path.resolve(__dirname, "..", "Resources", "public");
        const public = path.resolve(__dirname, "..", "Resources", "public", "assets");
        const bundleName = path.basename(path.resolve(__dirname, ".."));
        const publicPath = bundleName + "/assets/";

        let config = null;
        let dev = true;
        if (kernel.environment === "dev") {
          config = require("./webpack/webpack.dev.config.js");
        } else {
          config = require("./webpack/webpack.prod.config.js");
          dev = false;
        }

        module.exports = webpackMerge(config, {
          //context: context,
          target: "web",
          entry: {
            app: ["./Resources/js/app.js"],
            users: ["./Resources/js/users.js"]
          },
          output: {
            path: public,
            publicPath: publicPath,
            filename: "./js/[name].js",
            library: "[name]",
            libraryExport: "default"
          },
          externals: {},
          resolve: {},
          module: {
            rules: [{
                // BABEL TRANSCODE
                test: new RegExp("\.es6$|\.js$"),
                exclude: new RegExp("node_modules"),
                use: [{
                  loader: 'babel-loader',
                  options: {
                    presets: ['@babel/preset-env']
                  }
                }]
              },
              /*
               *	JQUERY EXPOSE BROWSER CONTEXT
               *
               */
              {
                test: require.resolve("jquery"),
                loader: "expose-loader?$!expose-loader?jQuery"
              }, {
                test: /jquery\..*\.js/,
                loader: "imports-loader?$=jquery,jQuery=jquery,this=>window"
              }, {
                test: /\.(sa|sc|c)ss$/,
                use: [
                  //'css-hot-loader',
                  MiniCssExtractPlugin.loader,
                  {
                    loader: "css-loader",
                    options: {
                      sourceMap: true
                    }
                  }, {
                    loader: 'resolve-url-loader',
                    options: {}
                  }, {
                    loader: 'postcss-loader', // Run post css actions
                    options: {
                      plugins: () => [require('precss'), require('autoprefixer')]
                    }
                  }, {
                    loader: "sass-loader",
                    options: {
                      sourceMap: true
                    }
                  }
                ]
              }, {
                test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
                use: [{
                  loader: 'file-loader',
                  options: {
                    name: '[name].[ext]',
                    outputPath: 'fonts/', // where the fonts will go
                    publicPath: `/${bundleName}/assets/fonts/` // override the default path
                  }
                }]
              }, {
                // IMAGES
                test: /\.(gif|png|jpe?g|svg)$/i,
                use: [{
                  loader: "file-loader",
                  options: {
                    name: "[name].[ext]",
                    publicPath: `/${bundleName}/assets/images/`,
                    outputPath: "/images/"
                  }
                }]
              }
            ]
          },
          plugins: [
            new MiniCssExtractPlugin({
              filename: "./css/[name].css",
              allChunks: true
            })
          ],
          devServer: {
            inline: true,
            hot: false
          }
        });
        		  </code></pre>

                    <p>Location :
                      <code>./app/config/webpack/webpack.prod.config.js</code>
                    </p>
                    <pre><code class="hljs javascript">const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
        const TerserPlugin = require('terser-webpack-plugin');

        module.exports = {
          mode: "production",
          watch: false,
          optimization: {
            minimizer: [
              new TerserPlugin({
                terserOptions: {
                  warnings: true,
                  compress: true
                },
                extractComments: true,
                cache: true,
                parallel: true
              })
            ]
          },
          plugins: [
            new OptimizeCssAssetsPlugin({
              cssProcessorOptions: {
                discardComments: {
                  removeAll: true
                }
              },
              canPrint: true
            })
          ]
        };
        		  </code></pre>
                  </div>
                </div>
              </div>
              <br>
              <h2 id="override">Override GLOBAL CONFIGURATION from Third-Party Bundles :</h2>
              <div class="doc2">
                <p>
                  To override global configuration from Third-Party Bundles you can write in config.js with the full name of bundle
                </p>
                <div class="alert  alert-info" role="alert">
                  WARNING to the order Registration bundles
                  <br>
                  If you want override a config of Third-Party bundle, this one must be register before the bundle config file who make the override
                </div>
                Example
                <code>./app/config/config.js
                </code>
                <pre><code class="hljs javascript">module.exports = {

          /**
           *  OVERRIDE ORM SEQUELIZE BUNDLE
           *
           *       @see SEQUELIZE BUNDLE config for more options
           *       @more options http://docs.sequelizejs.com/class/lib/sequelize.js~Sequelize.html
           *
           *       Nodefony Database Management
           *        dialect :               'mysql'|'sqlite'|'postgres'|'mssql'
           *
           *       By default nodefony create  connector name nodefony ( driver sqlite )
           *       for manage Sessions / Users
           *
           *       For mysql/mariadb create database nodefony before
           *       Mysql > CREATE DATABASE nodefony;
           *
           *       Here create new databases connectors
           *       and use for sync connectors :
           *       nodefony sequelize:sync
           */
          "sequelize-bundle": {
            debug: false,
            connectors: {
              nodefony: {
                driver: "mysql",
                dbname: 'nodefony',
                username: 'nodefony',
                password: 'nodefony',
                options: {
                  dialect: "mysql",
                  host: "localhost",
                  port: "3306",
                  pool:{
                    max:   5,
                    min:   0,
                    idle:  10000,
                    acquire:60000
                  }
                }
              }
            }
          },

          /**
           *  OVERRIDE MAIL Bundle
           *
           *   @see FRAMEWORK MAIL config for more options
           *     https://nodemailer.com
           *
           *   @examples :   gmail
           *    https://myaccount.google.com/security
           *
           *    nodemailer :{
           *      default : "gmail",
           *      transporters :{
           *        gmail : {
           *          host: "smtp.gmail.com",
           *          port: 465,
           *          secure: true, // true for 465, false for other ports
           *          auth: {
           *            user: "user@gmail.com",
           *            pass: "xxxxxxxxx"
           *          },
           *          tls: {
           *            // do not fail on invalid certs
           *            rejectUnauthorized: false
           *          }
           *        }
           *      }
           *    }
           */
          "mail-bundle": {
            nodemailer: {
              default: null,
              transporters: {
                free: {
                  host: "smtp.free.fr",
                  port: 465,
                  secure: true, // true for 465, false for other ports
                  auth: {
                    user: "", // generated  user
                    pass: "" // generated  password
                  }
                }
              }
            }
          }
        }
        </code></pre>

        Console started nodefony syslog :
        <pre><code class="hljs console">...
        ...
        mon oct 03 2016 17:10:41 warning bundle app  :  overriding  config bundle  : sequelize
        mon oct 03 2016 17:10:41 warning bundle app  :  overriding  config bundle  : mail
        </code></pre>


              </div>



      </main>
    </div>
  </div>
{% endblock %}
