App-Dochazka-WWW
view release on metacpan or search on metacpan
- script: dochazka-www: fix option pass-through to mfile-www
- ext: add MFILE_WWW_DISPLAY_SESSION_DATA to config example
- js: int-lib: fix undefined variable in log messages
- js: dform-init: improve data entry hint
- Dispatch: fix login bypass
- Some progress on create interval "last plus offset" and non-interactive async
dform population features
- js: display supervisor nick in employee profile
0.155 2017-10-20 22:43 CEST
- Dispatch: rename _login_dialog method to validate_user_credentials
- js: daction-init: fix pushable flag in one of the actions
- js: act-lib: use populate pattern for populateActivitiesCache
- js: implement employee profile caching
- js: upon successful masquerade, load full employee profile into cache
- js: move all cache-related code into a new caches.js module
- js: implement populateSchedIntvlsForDate() and populateSIDByDate()
0.156 2017-10-21 12:03 CEST
- build/ops: require App::MFILE::WWW 0.164
- js: fix ACL on schedule lookup/display
lib/App/Dochazka/WWW/Dispatch.pm view on Meta::CPAN
if ( ! $method or ! $path or ! $body ) {
$log->crit( 'POST request received, but missing mandatory attribute(s) - ' .
'here is the entire request body: ' . Dumper( $ajax ) );
return 0;
}
# two possibilities: login/logout attempt or normal AJAX call
if ( $method =~ m/^LOGIN/i ) {
$log->debug( "Incoming login/logout attempt" );
if ( $path =~ m/^login/i ) {
return $self->validate_user_credentials( $body );
} else {
return $self->_logout( $body );
}
}
# - normal AJAX call
$log->debug( "Calling rest_req $method $path on session ID " . $self->session_id );
$session->{'last_seen'} = time;
my $rr = $self->rest_req( {
server => $site->DOCHAZKA_WWW_BACKEND_URI,
method => $method,
path => $path,
req_body => $body,
} );
$log->debug( "rest_req returned: " . Dumper( $rr ) );
my $hr = $rr->{'hr'};
return $self->_prep_ajax_response( $hr, $rr->{'body'} );
}
=head2 validate_user_credentials
Called either from C<process_post> on login AJAX requests originating from the
JavaScript side (i.e. the login screen in login-dialog.js, via login.js), or
directly from C<is_authorized> if the MFILE_WWW_BYPASS_LOGIN_DIALOG mechanism
is activated.
Returns a status object - OK means the login was successful; all other statuses
mean unsuccessful.
=cut
sub validate_user_credentials {
my ( $self, $body ) = @_;
$log->debug( "Entering " . __PACKAGE__ . "::validate_user_credentials()" );
my $r = $self->request;
my $session = $self->session;
my $nick = $body->{'nam'};
my $password = $body->{'pwd'};
my $standalone = $meta->META_WWW_STANDALONE_MODE;
$log->debug( "Employee $nick login attempt" );
$log->debug( "DOCHAZKA_WWW_BACKEND_URI is " . $site->DOCHAZKA_WWW_BACKEND_URI );
share/js/dochazka-www/dform-init.js view on Meta::CPAN
'miniMenu': {
entries: ['createSingleIntSave'],
}
}); // createLastPlusOffset
target.push('createMultipleInt', {
'name': 'createMultipleInt',
'type': 'dform',
'menuText': 'Create multiple',
'title': 'Create multiple intervals according to schedule',
'preamble': "Hints: (1) TAB or ENTER to validate and advance to next field " +
"(2) enter month by name (e.g. \"June\") or number (e.g. \"6\"); " +
"DEFAULT: current month " +
"(3) enter days as " +
"an inclusive range (e.g. \"15-18\"), as a comma-separated list (e.g. " +
"\"7, 9, 28\"), or as a combination of the two (e.g. \"1, 3-5, 16-20\"); " +
"DEFAULT: entire month " +
"(4) Use 'Select activity' if you don't know activity code " +
'(5) Description is optional',
'aclProfile': 'active',
'entriesRead': [
share/js/dochazka-www/dform-init.js view on Meta::CPAN
'miniMenu': {
entries: ['selectActivityAction', 'createSingleIntSave'],
}
}); // createNextScheduled
target.push('createSingleInt', {
'name': 'createSingleInt',
'type': 'dform',
'menuText': 'Create',
'title': 'Create an arbitrary interval',
'preamble': "Hints: (1) TAB or ENTER to validate and advance to next field " +
"(2) date YYYY-MM-DD; year is optional " +
"(3) time range HH:MM-HH:MM or HH:MM+HH:MM (start time plus offset) " +
"or +HH:MM (last existing interval plus offset) or + (next scheduled " +
"interval) (4) Use 'Select activity' if you don't know activity code " +
'(5) Description is optional',
'aclProfile': 'active',
'entriesWrite': [entries.iNdate, entries.iNtimerange, entries.iNact, entries.iNdesc,],
'rememberState': true,
'miniMenu': {
entries: ['selectActivityAction', 'createSingleIntSave']
}
}); // createSingleInt
target.push('createLock', {
'name': 'createLock',
'type': 'dform',
'menuText': 'Create',
'title': 'Create a Lock',
'preamble': "Hints: (1) TAB or ENTER to validate and advance to next field ",
'aclProfile': 'active',
'entriesWrite': [entries.iNyear, entries.iNmonth,],
'rememberState': true,
'miniMenu': {
entries: ['createLockSave']
}
}); // createLock
target.push('createSingleIntFixedDay', {
'name': 'createSingleIntFixedDay',
'type': 'dform',
'menuText': 'Create',
'title': 'Create an arbitrary interval',
'preamble': "Hints: (1) TAB or ENTER to validate and advance to next field " +
"(2) time range HH:MM-HH:MM " +
"(3) Use 'Select activity' if you don't know activity code " +
'(4) Description is optional',
'aclProfile': 'active',
'entriesRead': [entries.iNdate,],
'entriesWrite': [entries.iNtimerangeNoOffset, entries.iNact, entries.iNdesc,],
'rememberState': true,
'miniMenu': {
entries: ['selectActivityAction', 'createSingleIntSave']
}
share/js/dochazka-www/dform-init.js view on Meta::CPAN
'miniMenu': {
entries: ['actionEmplSearch']
}
}); // searchEmployee
target.push('updateSingleInt', {
'name': 'updateSingleInt',
'type': 'dform',
'menuText': 'Update',
'title': 'Update an interval',
'preamble': "Hints: (1) TAB or ENTER to validate and advance to next field " +
"(2) time range HH:MM-HH:MM " +
"(3) Use 'Select activity' if you don't know activity code " +
'(4) Description is optional',
'aclProfile': 'active',
'entriesRead': [entries.iNdate, entries.acTaid],
'entriesWrite': [entries.iNtimerangeNoOffset, entries.iNact, entries.iNdesc,],
'rememberState': true,
'miniMenu': {
entries: ['selectActivityAction', 'updateSingleIntSave']
}
}); // updateSingleInt
target.push('viewIntervalsPrep', {
'name': 'viewIntervalsPrep',
'type': 'dform',
'menuText': 'View',
'title': 'View intervals for date or range of dates',
'preamble': "Hints: (1) TAB or ENTER to validate and advance to next field " +
"(2) enter month by name (e.g. \"June\") or number (e.g. \"6\"); " +
"DEFAULT: current month " +
"(3) enter days as a singleton (e.g. \"13\") or inclusive range (e.g. \"15-18\") " +
"DEFAULT: entire month",
'aclProfile': 'inactive',
'entriesRead': [
entries.iNdaterangeBegin,
entries.iNdaterangeEnd,
entries.iNyearHidden,
],
share/js/dochazka-www/dform-init.js view on Meta::CPAN
'miniMenu': {
entries: ['viewIntervalsAction']
}
}); // viewIntervalsPrep
target.push('viewLocksPrep', {
'name': 'viewLocksPrep',
'type': 'dform',
'menuText': 'View',
'title': 'View locks',
'preamble': "Hints: (1) TAB or ENTER to validate and advance to next field " +
"(2) enter month by name (e.g. \"June\") or number (e.g. \"6\"); " +
"DEFAULT: current month ",
'aclProfile': 'inactive',
'entriesWrite': [
entries.iNyear,
],
'rememberState': true,
'miniMenu': {
entries: ['viewLocksAction']
}
share/js/dochazka-www/int-lib.js view on Meta::CPAN
return true;
},
createMultipleIntSave = function (obj) {
var cu = currentUser('obj'),
daylist = $('input[id="iNdaylist"]').val(),
month = $('input[id="iNmonth"]').val(),
year = $('input[id="iNyear"]').val(),
dl = daylist.split(','),
i, rest, sc, fc;
// validate activity
if (obj.code) {
console.log("Looking up activity " + obj.code + " in cache");
i = appCaches.getActivityByCode(obj.code);
if (! i) {
coreLib.displayError('Activity ' + obj.code + ' not found');
return null;
}
obj.aid = i.aid;
} else {
coreLib.displayError("Interval activity code missing");
return null;
}
// validate day list
if (! coreLib.isArray(dl) || dl.length === 0) {
coreLib.displayError("Invalid day list");
return null;
}
for (i = 0; i < dl.length; i += 1) {
dl[i] = year + '-' + dt.monthToInt(month) + '-' + dl[i];
}
console.log("Date list", dl);
rest = {
"method": "POST",
( run in 0.601 second using v1.01-cache-2.11-cpan-a5abf4f5562 )