Delete all sessions on a coldfusion server - coldfusion

Is there a way to delete all current sessions for a specific application on a coldfusion server. I want to force all users to renew their session variables and add new session variables.
I thought about something like
<Cfset applicationStop()>
but i am not sure if it deletes all sessions. Even so, if it did i would still need to prevent it to delete all sessions for all applications. I just want to clear all sessions of 1 application and forces the execution of OnSessionStart (in application.cfc) for all users on that website/application.

Below is a snippet of an Application.cfc that will allow you to reset all session variables for an application. The controlling variable is application.loaded. You'll need to supply code that will change the value of this variable to force session reloads. When your code sets application.loaded to now(), it will have a date/time newer than session.loaded, it will reset the users session. This version is written in CF2016 level CFML.
This code is more of a template that you would have to revise for your implementation.
Application.cfc:
component displayname="myApp" {
this['Name'] = "myApp";
this['ApplicationTimeout'] = CreateTimeSpan(0, 12, 0, 0);
this['sessionTimeout'] = CreateTimeSpan(0, 0, 45, 0);
this['SessionManagement'] = true;
this['ClientManagement'] = false;
this['SetClientCookies'] = true;
public boolean function onApplicationStart() {
// app variable for session scope refresh
application['loaded'] = now();
return true;
} // onApplicationStart()
public void function onSessionStart() {
// this individual session loaded flag
session['loaded'] = now();
return;
} // onSessionStart()
public boolean function onRequestStart(required string targetPage) {
// if the applicaiton.loaded variable is more recent, force this session to be reset
if (application.keyExists("loaded") && session.keyExists("loaded") && application.loaded > session.loaded) {
// pick one or more of these FOUR options to reset the session.
// call the J2EE method of invalidating a session
getPageContext().getSession().invalidate();
// OR use the CF method
sessionInvalidate();
// OR clear the session struct
session.clear();
// OR clear important session variables that tell your app that the user is logged out, this will need to change based on YOUR implementation
session['user'] = "";
// if you clear the session with a form of invalidate(); onSessionStart() should be called to reset the session.loaded var. It can also be set here.
session['loaded'] = now();
// redirect to the target page, which should send the user back to the login page because the session was reset
location(url=arguments.targetPage, addtoken=false);
}
return true;
} // onRequestStart()
} // component
One oddity when I built this kind of system for a site is that; although applicationStop() was called, sessions did not clear. You'd think that sessions would be destroyed when the application was stopped, but they didn't. That's why I built this method. It seemed that sessions are tied to individual site cookies and are independent of the application that they may live in.

I u are not using single login method then use separate Application.cfm for each Application.
When you log out one Application then only One Application Session will be ended.
I cann't add this comment as I don't have permission.

Related

Storing temporary variables for use in Loopback 4 application

I have an authentication token I'd like to use in multiple Loopback 4 controllers. This token expires. Once expired I run some login logic to fetch a new token.
My issue is I'm not sure how or where to store this token.
So I can use this throughout my application I'm thinking to either save the token as a environment variable eg.
process.env.AUTH_TOKEN = 'TEST';
or use Loopback 4's Application-level context
https://loopback.io/doc/en/lb4/Context.html
Are these suitable solutions for storing this token? If not what would be an alternative solution?
In the case of using Context, how would I go about doing this using best practices?
Taking all the comments above into account I would recommend you to crate a separate module which will encapsulate the logic related to your authentication token and how you use it. I.e. a new module will be responsible for:
Fetching a new token when it is empty
Storing of the token
Refreshing the token when it has expired
Execution of the API calls (or whatever you do with that token, sorry it was not clear from your description) - can be moved to a separate module, but it is a different story
I imagine your module in JavaScript may look something like:
let AUTH_TOKEN = "";
function makeAPICall(some, params) {
if (! AUTH_TOKEN) {
acquireNewToken();
}
if (expired()) {
refreshToken();
}
return "some_data"; // TODO: here you do you what you want with your auth token and return some data
}
function acquireNewToken() {
authToken = "new_token"; // TODO: put the logic to acquire a new token here
}
function refreshToken() {
authToken = "new_token"; // TODO: put the logic to refresh a token here
}
function expired() {
return false; // TODO: put the logic to check if token expired here
}
module.exports = {
makeAPICall: makeAPICall
};
Then you can require the authModule in all your controllers and use it like below:
let authModule = require('./modules/authModule');
authModule.makeAPICall("some", "params");
I believe you will never need to expose the auth token to your controllers as you can implement all the logic related to auth token usage within the authModule and only pass some parameters to makeAPICall function to tell it what to do and which data to get. But in case if you really need to expose it you can change the authModule a bit (add getToken function and add it to module.exports):
function getToken() {
return authToken;
}
module.exports = {
makeAPICall: makeAPICall,
getToken: getToken
};
Now, let's get back to your questions:
Are these suitable solutions for storing this token? If not what would be an alternative solution?
As proposed above the solution is to store the token as a local variable in scope of custom module. Note, as Node.js uses caching for modules your AUTH_TOKEN variable will be the same across all the controllers (every new require will return you exactly the same object with the same token).
If you do not want to require the authModule every time you need to access your AUTH_TOKEN you can also simply declare it as a global variable: global.AUTH_TOKEN = "";. Note, that global variables have it's drawback like it may cause implicit coupling between files, etc. Here is a good article about when you should and when you should not use global variables: https://stackabuse.com/using-global-variables-in-node-js/
In the case of using Context, how would I go about doing this using
best practices?
You can use Loopback 4 Context as well and it will be almost an equivalent of the solution with the custom authModule I proposed above. The only difference with the customer module - you can put a bit more custom logic there and avoid copy-pasting some of your code in the controllers. With Loopback 4 Context you can use Server level context and store your AUTH_TOKEN there, but you will still need some place where you get a new token and refresh it when it expires. Again, you can implement this logic in the custom authModule. I.e. you can still keep that custom module and store the AUTH_TOKEN in Loopback Context at the same time. This will be absolutely OK, but it will make the code a bit more complex from my point of view.

How can you check if the user's browser supports Google Caja?

I'm using Google Caja to sanitize user input on my site. I'm currently processing the user's input inside the callback I pass to caja.whenReady(). However, on Microsoft Edge, the callback is never called because Edge can't be made safe by Caja. In the event that Caja doesn't work, I want to fall back to processing the user's content server side where I'll simply strip out all JavaScript.
How can I check if Caja works with the user's browser?
The code below will give you a function, browserSupportsCaja() that will return true at any time after Caja calls its whenReady() callbacks. This way you can determine if Caja is supported after it initializes.
If you check for Caja support before it finishes initializing, then you will get a false negative. To catch that, just put the code that you want to execute after Caja is ready in a whenReady() callback and assume that Caja is not available anywhere else.
caja.initialize({
cajaServer: 'https://caja.appspot.com/'
});
function browserSupportsCaja() {
return browserSupportsCaja.return_value;
}
browserSupportsCaja.return_value = false;
caja.whenReady( function() {
browserSupportsCaja.return_value = true;
});

cgi.SERVER_NAME reverts origin

I have two versions of a site, one for spanish, one for english. The spanish subdomain is set via IIS and a C Name (network admin told me, I'm not sure how or what that means), it's not a separate subdomain.
es.website.com
en.website.com
Now, when I use CGI.SERVER_NAME on my development server, everything works nicely. However, in production, when I'm on es.website.com, despite my Application.cfc settings, it thinks the origin is en.website.com, which throws off my <cfheader name="Access-Control-Allow-Origin" value="#application.site#">.
Here is how I differentiate the domains and sites to determine which content must be in spanish:
application.subdomain = ListFirst(cgi.SERVER_NAME, ".");
if (application.test) {
if (application.subdomain == "en") {
application.site = "http://en.dev.website.com/";
} else {
application.site = "http://es.dev.website.com/";
}
} else {
if (application.subdomain == "en") {
application.site = "http://en.website.com/";
} else {
application.site = "http://es.website.com/";
}
}
I cannot figure out why when on other pages, application.sites is clearly es.website.com, yet on some pages, the cgi.server_name reverts to en.website.com. Any insight?
If you are storing it in an application scoped variable then users can change the variable mid request. You don't see this on your dev server because you don't have any concurrent users.
Assume you have a request to en.website.com then 1 millisecond later a request to es.website.com both requests will share the same application scope, the second request will change the value of application.site to the ES version.
A better solution would be to use a request scoped variable for this since the value differs by request.
Another less elegant solution would be to make sure each site has a different application name, for example:
this.name = LCase(cgi.server_name) & "_website";
That would cause each domain to have its own application scope, which depending on how your web server is setup could lead to a denial of service condition (if you allow any domain to hit the application).

Flex database - HTTP call collision?

I have a Flex application for AIR. I fetch some data from a JSON-RPC web service through the mx.rpc.http.HTTPService class. I make all the calls asynchronously. When the results return I process them and put the data into an SQLite database through the flash.data.SQLConnection. This means quite some updates per web service calls so every callback starts a transaction, does the updates and then commits.
According to my debug console tracing I see two kinds of behaviour: either a callback successfully begins a transaction, calls the transaction event handler function, does all the updates, commits and then the next web service call returns. Or a callback successfully begins a transaction and as the next web service call returns (without trying to start a new transaction yet) the previous callback just... ceases to exist even before the callback of the beginning of the transaction.
Is that a bug in Flex? Or in AIR? Or in ActionScript? Or in the specific components? Do I do something wrong? Is this just my misunderstanding? (I'm just trying my wings in Flex, I don't really know what to expect from the system or how to handle this situation.)
Some code from my database manager class
public function beginTransaction(handler:Function):void {
// The calls are all fine up to this point
conn.begin(SQLTransactionLockType.DEFERRED, new Responder(handler, OnError));
// Begin is always called first. If another web service call doesn't come
// back up to this point then it won't until I call commit in an other
// function.
trace("this always runs yet");
// But if another call comes back just after begin is called then handler
// won't get called. Even though the previous trace still will.
}
My web service call
public function getWSCall(url:String, method:String, param:Object,
handler:Function):void
{
var http:HTTPService = new HTTPService();
http.addEventListener(FaultEvent.FAULT, JsonError);
http.addEventListener(ResultEvent.RESULT, handler);
http.url = url;
http.method = "POST";
http.contentType = "application/json";
var params:Object = {};
params.jsonrpc = "2.0";
params.method = method;
if (param !== null)
params.params = param;
params.id = method;
var json:String = JSON.stringify(params);
trace (url + " " + json);
http.send(json);
}
And an example of how I call it
JsonConnector.instance.getWSCall(WSConstants.GET_DATA_URL,
WSConstants.GET_DATA_METHOD, param, getDataCompleted);
And in the getDataCompleted after some rearrangement I call my database manager class where I finally begin the transaction:
dbConnector.Open(key, opened);
function opened(event:SQLEvent):void
{
if(event.type == SQLEvent.OPEN) {
dbConnector.beginTransaction(onBegin);
}
}

Cannot get onSession Start to fire in Mura

I have a script :
<cfscript>
gf = createObject('component','com.general');
gf.checkIpBlocked();
</cfscript>
that I want to fire onSessionStart.
I added an onSessionStart to /siteID/includes/themes/myTheme/eventHandler.cfc. But the session start NEVER fires. I know there is something managing sessions because of I open the admin, login then close the browser, re-open it I am forced to login again.
If I set a session variable close the browser and and the session.testVar never goes away and seems to hold the initial value for a very long time.
I am not trying to manage mura users or anything I am just trying to set a session variable the first time in a "session". In a typical application.cfc this is easy.
Any insight is appreciated.
Unfortunately, that's a bug. However, one thing to keep in mind is that onSiteSessionStart is unreliable since it only fires when a siteID is defined within the request. For example, if you were to go to the admin and be asked to login your session will have started and there would have been no siteID.
For now I would try using onSiteRequestStart to param the variable instead.
function onSiteRequestStart($){
param name="session.ipChecked" default=false;
if(!session.ipChecked){
var gf = createObject('component','com.general');
gf.checkIpBlocked();
session.ipChecked=true;
}
}
In regard to our documentation we have three Mura 6 books available both printed and digital downloads from Lulu
And are also working to create a systematic way to post the contents of those books on our support site which we are hoping to complete by MuraCon on 9/30. So that the all of our documentation will stay update and in sync.
The Mura docs state that the application events are actually onGlobalSessionStart and/or onSiteSessionStart.
Application Events
onApplicationLoad onSiteSessionStart
onGlobalSessionStart onSiteSessionEnd
onSiteMissingTemplate onSiteError
onGlobalError onBeforeAutoUpdate
onAfterAutoUpdate onGlobalThreatDetect
Note that Events that begin with onGlobal are deļ¬ned on a per-Mura
instance basis.
Mura docs.