CodeIgniter 4/Multiple Websites/Shared Resources - codeigniter-4

I am setting up multiple websites with CodeIgniter 4 that will share the same resources (IE: Models, Library, Helpers, ThirdParty, etc). My goal is to be able to manage code updates and migrations in the shared resources so the changes are global throughout all the websites. Below is an example of the structure:
SYSTEM_CI4 (Shared by all CI4 installations)
RESOURCES (Shared by all CI4 installations)
WEBSITE_1 (CI4)
WEBSITE_2 (CI4)
WEBSITE_4 (CI4)
ETC (CI4)
How can I use the shared resource in WEBSITE_1 while it is outside of the directory?
Any help would be greatly appreciated!
Thank you in advance!!!

This is quite easy in CI4.
Following is one of the approaches that you can take for achieving this.
Let's say the default setup is app -> CI4 folders.
Then, you will need to create another folder, let's say Website1 on the same level as your base app folder in CI4.
Once you do this, the Routes of the Website1 should be stored within the Website1 folder with the same folder structure as the original CI4 project.
Migrations will be within Website1/app/Migrations folder and if your connections are different then you will need to either mention the connection name on the migrations or switch them dynamically.
For the CI4 to find your websites routes successfully, you will need to mention the routes in Autoload file as follow:
$psr4 = [
'App' => APPPATH, // To ensure filters, etc still found,
APP_NAMESPACE => APPPATH, // For custom namespace
'Config' => APPPATH . 'Config',
'Website1' => ROOTPATH .'Website1',
'Website1/app' => ROOTPATH .'Website1/app'
This will enable you to use the classes defined within App or Website1 to be used anywhere in the CI4 project.
Example of Folder Structure :
Resources to be shared :
app\Config\ <-- For shared Configurations
app\Models\ <-- For shared Models
app\Database\Migrations\ <-- For shared Migrations
Website1 Folder:
Website1\app\Config\ <-- For Website1 Configurations
Website1\app\Models\ <-- For Website1 Models
Website1\app\Database\Migrations\ <-- For Website1 Migrations

Related

Next.JS security of directory structure and JSON secrets

I have a security question regarding the access of Next.JS directories, and their access requirements. I have a root folder that has my pages, public, src, styles, models folders. In the src folder I have a settings.json file that is a empty JavaScript object. The idea is that settings would be added to this file and accessed by api routes, to check settings that could be modified on this settings.json file... What I am wondering is if the client can actually somehow just read/access the src directory and get the settings.json file. I want to put secret key's here that way I can easily change secret keys without having to restart my server. So I could just update the secret key live, and have it applied to the settings.json file. Then the update would be live immediately and I don't have to change the environment variables and restart the server.
Is it safe to keep and use a json file in the src directory to store confidential data? If not, is there a way to keep and use a json file for this purpose?
Thanks for the help and info.
As juliomalves pointed out client code won't be able to access a directory or file that you have on the server with the exception of the public directory.
Next gives you the ability to serve static assets from [root]/public as documented here
Note: Only assets that are in the public directory at build time will be served by Next.js.
If this directory is ever renamed, these assets are no longer available from a client.
Note: Don't name the public directory anything else. The name cannot be changed and is the only directory used to serve static assets.
"I put a settings.json file right next to that .env file and required it in an api route, could the client somehow download that settings.json file without me purposely sending them the contents/file itself?"
The only way information can be served from an api route is by expressly creating a route to call res[ponse].send() (or res.json()) with data imported from that file. Api routes are not ever bundled on the client side and only ever exist on the server as noted here.
Any file inside the folder pages/api is mapped to /api/* and will be treated as an API endpoint instead of a page. They are server-side only bundles and won't increase your client-side bundle size.
"What I am wondering is if the client can actually somehow just read/access the src directory and get the settings.json file."
As noted above only assets in the /public directory are accessible as files by path. Directories are never accessible in Next as static assets. This is even pointed out in the source code.
send(req, path)
.on('directory', () => {
// We don't allow directories to be read.
const err: any = new Error('No directory access')
err.code = 'ENOENT'
reject(err)
})

How to setup StencilJS components on S3 and CloudFront

I have a few components and I want to deploy them into S3 and make them reachable with CloudFront.
My problem is that I don't know what file(s) I need to upload to S3 and which file needs CloudFront needs to point to as entry point.
Here's my stencil.config.tsx:
import { Config } from '#stencil/core';
export const config: Config = {
namespace: 'stencil-test',
taskQueue: 'async',
outputTargets: [
{
type: 'dist',
esmLoaderPath: '../loader',
dir: './build/dist'
},
{
type: 'www',
serviceWorker: null // disable service workers
}
]
};
I tried executing npm run build that generated a couple of folders: build/loader and build/dist there's a lot of stuff within each folder but I have no idea how which folder and files are supposed to do what.
It was hoping the build command would generate a minified file that contained all the stuff needed (is this how it works?) so I could eventually do something like the following where I want to use my components:
<script type="module" src='https://cdn.jsdelivr.net/npm/my-name#0.0.1/dist/myname.js'></script>
Can anyone offer some guidance or point me towards any resources?
The www output target is meant for generating apps and not really relevant for component libraries. To host your components, you should upload the whole generated dist folder. Only the files that the client needs are downloaded, which depends on the client and which components they access (lazy-loading). So you don't need to worry about the amount of files. See https://stenciljs.com/docs/distribution.
To start, Stencil was designed to lazy-load itself only when the component was actually used on a page. There are many benefits to this approach, such as simply adding a script tag to any page and the entire library is available for use, yet only the components actually used are downloaded.
If you want to generate a single bundle containing all your components, there's an output target called dist-custom-elements-bundle. For the differences to dist you can have a look at the same docs link above.
One of the main differences is that loading the script doesn't automatically register the components for you, you'll have to either do it manually per component (using customElements.define(), or define them all using the defineCustomElements() export. The official documentation for that output target is https://stenciljs.com/docs/custom-elements.

Securing files in Google Cloud app engine (NodeJS)

I have created a small web application with NodeJS Express. Basically a webserver that has a 'webserver.properties' file. With a very basic app.yaml file.
After deploying it to Google Cloud by use of 'gcloud app deploy' I get the everything up and running.
However...when I open the following URL in the browser: https://webserverurl.com/webserver.properties , the webserver.properties file can be approached and is in turn downloaded immediately.
How can I prevent this from happening and make sure that such properties files are inaccessible from outside?
The problem is that when you use this line:
app.use('/', express.static(__dirname + '/'));
you are giving access to your root directory. See this for a definition of __dirname. If you want to give access to a specific folder you can do this:
Lets say your root directory is src and you fave a dir with static files called src/myfiles. In order to give acces to files in myfiles you can use this line:
app.use('/mypathname', express.static('myfiles'));
where:
'/mypathname' is the part pertaining your URL. In your case it would be https://webserverurl.com/mypathname/any-file-name.jpg
express.static('myfiles') is the name of your local dir.
See this guide.
Hope this helps

How do you change the express static directories?

I am working on a development platform, I have code similar to the following:
app.use('/public', express.static( config.directory.public ));
The issue is that there are many (100s) of projects each with its own directory structure. The project will be selected via the URL:
http://localhost/dev/accounts
Where accounts is a project with its own directory tree and static public directory.
I do not want to run a separate copy of node for each project. Once a project has been selected via the URL then express needs to be reconfigured to serve files for that request.
However, that approach is probably not feasible because we may be working on many projects at the same time. So every request for static files would have to be processed according to the project URL. It seems to negate the benefit of static directories.
I think what I am after is a way to put variables into the directory path
http://localhost/dev/accounts
Would set a variable called prj = "accounts" and then somehow set express so that the root directory is "c:\projects\" + prj + "\public".
If I simply issue a new app.use(..) statement for every request I imagine bad things will happen.
Maybe I am better off just manually reading the file contents for each static request and sending the contents back.
Is there another way to approach this problem?
I'm not sure if I understood your question correctly, but express serves static files in file directories automatically for you. If you have a bunch of projects in some 'path/to/public' folder, you just need to do something like
app.use('/', express.static( __dirname + '/public' ));
That way, you just need to type some url like
http://localhost/project1
or
http://localhost/project2

Exts4.2 MVC application minfication using JSBuilder2 and Maven

We have developed an application using Extjs 4.2 following MVC pattern. We have project folder setup as follwing:
WebContent
--> app
-->controller
-->model
-->store
-->view
app.html
app.js
In app.js we have defined all models, controllers, stores under Ext.application. Like:
Ext.application({
name: 'MyProject',
autoCreateViewport: true,
models: [
'Model1',
'Model2'
],
stores: [
'store1',
'store2'
]
(views and controllers similarly)
This all works good for us. Now we need to concatenate all these models, stores, controllers, views into one app-all.js and use it in our app.html. I have read many posts on net on how to do that with Sencha cmd tool, but none of them was application to me as we have a restriction to install cmd tool and we need to generate concatenated and minified file on build time with Maven.
I found out a solution that by using JSBuilder2, I can get a concatenated + minified app.js.
Problem is now when I use this minified file, all individual js files are still being downloaded. As if I delete individual js files, I get 404 error and application fails to load.
I suppose that is because of way we have defined models, views, controllers in our app.js; they are still looking for js class files in respective folders.
Please share if you have any solution to this.
You can disable the dynamic loader using the enabled property of Ext.Loader (http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.Loader-cfg-enabled):
Ext.Loader.setConfig({ enabled: false })
You must place this code after including the framework files, but before your application files.
This should prevent Ext JS from trying to download files. You need to make sure all framework and application classes that you use are included on the page.

Resources