2 |
8 |
--------------------------------------------------------------------------------
/app/views/partials/audit-operation.html:
--------------------------------------------------------------------------------
1 |
2 | {{expanded ? 'Hide' : 'Show'}}
3 |
4 |
Made {{audit.ops.length}} change(s)
5 |
6 |
7 |
8 |
9 |
10 |
11 | Added {{op.path}} with value:
12 |
{{op.value | json}}
13 |
14 |
15 | Added {{op.path}} with value {{op.value | json}}
16 |
17 |
18 |
19 |
20 |
21 | Replaced {{op.path}} with:
22 |
{{op.value | json}}
23 |
24 |
25 | Replaced {{op.path}} with {{op.value | json}}
26 |
27 |
28 |
29 |
Removed {{op.path}}
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/views/partials/channels-tab-logs.html:
--------------------------------------------------------------------------------
1 |
2 | No audits found
3 |
4 |
5 |
6 |
7 | Date
8 | User
9 | Changes
10 |
11 |
12 |
13 |
14 | {{audit.date | date:'medium'}}
15 | {{audit.updatedBy.name}}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/views/partials/channels-tab-user-access.html:
--------------------------------------------------------------------------------
1 |
2 | Manage the users and group that have access to view or rerun this channel's transactions. Ensure that these restrictions are used to hide an sensitive information that may be contained in a transaction. By default only admins can view and interact with a channel's transactions.
3 |
4 |
5 |
6 |
7 | Which user groups are allowed to view this channel's transactions?
8 |
9 |
10 |
11 |
12 |
13 |
14 | Which user groups are allowed to view this channel's transactions full request/response body?
15 |
16 |
17 |
18 |
19 |
20 |
21 | Which user groups are allowed to rerun this channel's transactions?
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/views/partials/clients-tab-basic-info.html:
--------------------------------------------------------------------------------
1 |
Describe some basic information about the client.
2 |
3 |
15 |
16 |
26 |
36 |
46 |
47 |
64 |
--------------------------------------------------------------------------------
/app/views/partials/mediator-config-display.html:
--------------------------------------------------------------------------------
1 |
62 |
--------------------------------------------------------------------------------
/app/views/partials/metrics-date-type-selector.html:
--------------------------------------------------------------------------------
1 |
42 |
--------------------------------------------------------------------------------
/app/views/partials/taskDetails-filter-settings.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Basic Filters:
4 |
5 | Processing Status:
6 |
10 | Don't filter
11 | Show Queued
12 | Show Processing
13 | Show Failed
14 | Show Completed
15 |
16 |
17 |
18 | Rerun Status:
19 |
23 | Don't filter
24 | Show Failed
25 | Show Processing
26 | Show Completed
27 | Show Completed with error(s)
28 | Show Successful
29 |
30 |
31 |
32 | Has Errors:
33 |
37 | Don't filter
38 | Yes
39 | No
40 |
41 |
42 |
43 |
44 | Limit:
45 |
46 |
47 |
48 | 10
49 | 50
50 | 100
51 | 200
52 | 500
53 |
54 |
55 |
56 |
57 |
58 | Clear Filters
59 |
60 |
--------------------------------------------------------------------------------
/app/views/partials/tasks-filter-settings.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Basic Filters:
4 |
5 |
6 | Status:
7 |
8 |
9 |
13 | Don't filter
14 | Show Queued
15 | Show Processing
16 | Show Paused
17 | Show Cancelled
18 | Show Completed
19 |
20 |
21 |
22 |
23 | User:
24 |
25 |
26 |
31 | Don't filter
32 |
33 |
34 |
35 |
36 |
37 | Date:
38 |
39 |
40 |
49 |
50 |
51 |
52 | Limit:
53 |
54 |
55 |
60 |
61 |
62 |
63 |
64 |
65 | Clear Filters
66 |
67 |
--------------------------------------------------------------------------------
/app/views/partials/user-settings-tabs.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | List Settings
5 |
6 |
7 | Transaction View
8 |
9 |
10 |
11 | Same Tab
12 | New Tab
13 |
14 |
15 |
16 |
17 | Auto-Update Transaction List
18 |
19 |
20 |
21 | Enabled
22 | Disabled
23 |
24 |
25 |
26 |
27 |
28 |
29 | General Settings
30 |
31 |
32 | Show Tooltips
33 |
34 |
35 |
36 | Yes
37 | No
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/views/sidebar.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/views/transactionsBodyModal.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
15 |
--------------------------------------------------------------------------------
/app/views/transactionsRerunModal.html:
--------------------------------------------------------------------------------
1 |
5 |
53 |
--------------------------------------------------------------------------------
/app/views/visualizerModal.html:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
36 |
--------------------------------------------------------------------------------
/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | # Set defaults for the environment variables
2 | export OPENHIM_CONSOLE_PROTOCOL=${OPENHIM_CONSOLE_PROTOCOL:-"https"}
3 | export OPENHIM_CONSOLE_HOSTPATH=${OPENHIM_CONSOLE_HOSTPATH:-""}
4 | export OPENHIM_CORE_MEDIATOR_HOSTNAME=${OPENHIM_CORE_MEDIATOR_HOSTNAME:-"localhost"}
5 | export OPENHIM_MEDIATOR_API_PORT=${OPENHIM_MEDIATOR_API_PORT:-"8080"}
6 | export OPENHIM_MEDIATOR_HEALTH_WARNING_TIMEOUT=${OPENHIM_MEDIATOR_HEALTH_WARNING_TIMEOUT:-"60"}
7 | export OPENHIM_MEDIATOR_HEALTH_DANGER_TIMEOUT=${OPENHIM_MEDIATOR_HEALTH_DANGER_TIMEOUT:-"120"}
8 | export OPENHIM_CONSOLE_SHOW_LOGIN=${OPENHIM_CONSOLE_SHOW_LOGIN:-"true"}
9 | export KC_OPENHIM_SSO_ENABLED=${KC_OPENHIM_SSO_ENABLED:-"false"}
10 | export KC_FRONTEND_URL=${KC_FRONTEND_URL:-"http://localhost:9088"}
11 | export KC_REALM_NAME=${KC_REALM_NAME:-"platform-realm"}
12 | export KC_OPENHIM_CLIENT_ID=${KC_OPENHIM_CLIENT_ID:-"openhim-oauth"}
13 |
14 | cat config/default-env.json | envsubst | tee config/default.json
15 |
16 | nginx -g "daemon off;"
17 |
--------------------------------------------------------------------------------
/infrastructure/centos/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM centos
2 |
3 | LABEL Jembi Health Systems NPC
4 |
5 | # install dependencies
6 | RUN yum install -y gcc gcc-c++ \
7 | make cmake git \
8 | rpm-build redhat-rpm-config && \
9 | yum clean all
10 |
11 | RUN curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
12 | RUN source ~/.bashrc
13 | RUN nvm install --lts
14 | RUN npm --version && node -v
15 |
--------------------------------------------------------------------------------
/infrastructure/centos/Vagrantfile:
--------------------------------------------------------------------------------
1 | # -*- mode: ruby -*-
2 | # vi: set ft=ruby :
3 |
4 | # All Vagrant configuration is done below. The "2" in Vagrant.configure
5 | # configures the configuration version (we support older styles for
6 | # backwards compatibility). Please don't change it unless you know what
7 | # you're doing.
8 | Vagrant.configure("2") do |config|
9 | # The most common configuration options are documented and commented below.
10 | # For a complete reference, please see the online documentation at
11 | # https://docs.vagrantup.com.
12 |
13 | # Every Vagrant development environment requires a box. You can search for
14 | # boxes at https://vagrantcloud.com/search.
15 | config.vm.box = "centos/7"
16 |
17 | # Disable automatic box update checking. If you disable this, then
18 | # boxes will only be checked for updates when the user runs
19 | # `vagrant box outdated`. This is not recommended.
20 | # config.vm.box_check_update = false
21 |
22 | # Create a forwarded port mapping which allows access to a specific port
23 | # within the machine from a port on the host machine. In the example below,
24 | # accessing "localhost:8080" will access port 80 on the guest machine.
25 | # NOTE: This will enable public access to the opened port
26 | # config.vm.network "forwarded_port", guest: 80, host: 8080
27 |
28 | # Create a forwarded port mapping which allows access to a specific port
29 | # within the machine from a port on the host machine and only allow access
30 | # via 127.0.0.1 to disable public access
31 | # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
32 |
33 | # Create a private network, which allows host-only access to the machine
34 | # using a specific IP.
35 | # config.vm.network "private_network", ip: "192.168.33.10"
36 |
37 | # Create a public network, which generally matched to bridged network.
38 | # Bridged networks make the machine appear as another physical device on
39 | # your network.
40 | # config.vm.network "public_network"
41 |
42 | # Share an additional folder to the guest VM. The first argument is
43 | # the path on the host to the actual folder. The second argument is
44 | # the path on the guest to mount the folder. And the optional third
45 | # argument is a set of non-required options.
46 | # config.vm.synced_folder "/source", "/destination"
47 |
48 | # Provider-specific configuration so you can fine-tune various
49 | # backing providers for Vagrant. These expose provider-specific options.
50 | # Example for VirtualBox:
51 | #
52 | # config.vm.provider "virtualbox" do |vb|
53 | # Display the VirtualBox GUI when booting the machine
54 | # vb.gui = true
55 |
56 | # Customize the amount of memory on the VM:
57 | # vb.memory = "1024"
58 | # end
59 | #
60 | # View the documentation for the provider you are using for more
61 | # information on available options.
62 |
63 | # Enable provisioning with a shell script. Additional provisioners such as
64 | # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
65 | # documentation for more information about their specific syntax and use.
66 | config.vm.provision "shell", privileged: false, inline: <<-SHELL
67 | sudo yum -y update
68 | sudo yum install -y git rpm-build redhat-rpm-config gcc-c++ make
69 |
70 | curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
71 | sudo yum install -y nodejs
72 |
73 | # download master and install dependencies
74 | git clone https://github.com/jembi/openhim-console.git
75 | cd openhim-console/
76 | npm install && npm install speculate
77 |
78 | # generate SPEC file for rpmbuild
79 | npm run spec
80 |
81 | # Link source folder with default rpmbuild
82 | ln -s ~/openhim-console ~/rpmbuild
83 |
84 | #Build rpm package
85 | rpmbuild -bb ~/rpmbuild/SPECS/openhim-console.spec
86 | SHELL
87 |
88 | end
89 |
--------------------------------------------------------------------------------
/infrastructure/development/env/.gitignore:
--------------------------------------------------------------------------------
1 | .vagrant
2 |
--------------------------------------------------------------------------------
/infrastructure/development/env/Vagrantfile:
--------------------------------------------------------------------------------
1 | # -*- mode: ruby -*-
2 | # vi: set ft=ruby :
3 |
4 | VAGRANTFILE_API_VERSION = "2"
5 |
6 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
7 |
8 | # Use trusty64 base box
9 | config.vm.box = "ubuntu/trusty64"
10 | config.vm.provider "virtualbox" do |v|
11 | v.customize ["modifyvm", :id, "--memory", 1024]
12 | end
13 |
14 | # Configure port forwarding
15 | config.vm.network "forwarded_port", guest: 9000, host: 9000
16 |
17 | config.vm.provision :shell do |shell|
18 | shell.inline = "mkdir -p /etc/puppet/modules;
19 | puppet module install willdurand/nodejs"
20 | end
21 |
22 | # Setup LC_ALL locale flag
23 | config.vm.provision :shell do |shell|
24 | shell.inline = "echo 'LC_ALL=\"en_US.UTF-8\"' >> /etc/default/locale"
25 | end
26 |
27 | config.vm.synced_folder "../../../", "/openhim-console"
28 |
29 | config.vm.provision :puppet do |puppet|
30 | puppet.manifests_path = "./"
31 | puppet.manifest_file = "openhim-console.pp"
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/infrastructure/development/env/openhim-console.pp:
--------------------------------------------------------------------------------
1 | # Puppet manifest
2 | #
3 | # Required modules:
4 | # willdurand/nodejs
5 | #
6 |
7 | # defaults for Exec
8 | Exec {
9 | path => ["/bin", "/sbin", "/usr/bin", "/usr/sbin", "/usr/local/bin", "/usr/local/sbin", "/usr/local/node/node-default/bin/"],
10 | user => "root",
11 | }
12 |
13 | # Install required packages
14 | Package { ensure => "installed" }
15 | package { "git": }
16 | package { "libfontconfig1": }
17 |
18 | class { "nodejs":
19 | version => "stable",
20 | make_install => false,
21 | }
22 |
23 | exec { "npm-install":
24 | cwd => "/openhim-console",
25 | command => "npm install",
26 | require => Class["nodejs"],
27 | }
28 |
29 | exec { "install-bower":
30 | cwd => "/openhim-console",
31 | command => "npm install -g bower",
32 | unless => "npm list -g bower",
33 | require => Class["nodejs"],
34 | }
35 |
36 | exec { "install-grunt":
37 | cwd => "/openhim-console",
38 | command => "npm install -g grunt-cli",
39 | unless => "npm list -g grunt-cli",
40 | require => Class["nodejs"],
41 | }
42 |
43 | exec { "bower-install":
44 | cwd => "/openhim-console",
45 | command => "bower --allow-root install",
46 | require => Exec["install-bower"],
47 | }
48 |
--------------------------------------------------------------------------------
/infrastructure/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 | networks:
3 | openhim:
4 |
5 | services:
6 | mongo-db:
7 | container_name: mongo-db
8 | image: mongo:4.0
9 | networks:
10 | - openhim
11 | volumes:
12 | - "mongo-data:/data/db"
13 | restart: unless-stopped
14 |
15 | openhim-core:
16 | container_name: openhim-core
17 | image: jembi/openhim-core:latest
18 | restart: unless-stopped
19 | environment:
20 | mongo_url: "mongodb://mongo-db/openhim-dev"
21 | mongo_atnaUrl: "mongodb://mongo-db/openhim-dev"
22 | NODE_ENV: "production"
23 | ports:
24 | - "8080:8080"
25 | - "6000:5000"
26 | - "6001:5001"
27 | networks:
28 | - openhim
29 | healthcheck:
30 | test: "curl -sS http://openhim-core:8080/heartbeat || exit 1"
31 | interval: 30s
32 | timeout: 30s
33 | retries: 3
34 |
35 | openhim-console:
36 | container_name: openhim-console
37 | image: jembi/openhim-console:latest
38 | restart: unless-stopped
39 | networks:
40 | - openhim
41 | ports:
42 | - "9090:80"
43 | volumes:
44 | - "../app/config/default.json:/usr/share/nginx/html/config/default.json"
45 | healthcheck:
46 | test: "curl -sS http://openhim-console || exit 1"
47 | interval: 30s
48 | timeout: 30s
49 | retries: 3
50 |
51 | volumes:
52 | mongo-data:
53 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // Karma configuration
4 | // http://karma-runner.github.io/0.10/config/configuration-file.html
5 |
6 | module.exports = function (config) {
7 | config.set({
8 | // base path, that will be used to resolve files and exclude
9 | basePath: '',
10 |
11 | // testing framework to use (jasmine/mocha/qunit/...)
12 | frameworks: ['mocha', 'sinon-chai', 'dirty-chai'],
13 |
14 | // list of files / patterns to load in the browser
15 | files: [
16 | 'node_modules/angular/angular.js',
17 | 'node_modules/angular-mocks/angular-mocks.js',
18 | 'node_modules/moment/moment.js',
19 | 'dist/bundle.js',
20 | { pattern: 'dist/bundle.js.map', included: false, watched: false },
21 | 'dist/index.html',
22 | { pattern: 'dist/fonts/*', watched: false, included: false, served: true, nocache: false },
23 | 'test/spec/controllers/*.js',
24 | 'test/spec/services/*.js'
25 | ],
26 | proxies: {
27 | '/fonts/': 'http://localhost:8090/base/dist/fonts/'
28 | },
29 | reporters: ['mocha'],
30 |
31 | // list of files / patterns to exclude
32 | exclude: [],
33 |
34 | captureTimeout: 300000,
35 | browserDisconnectTolerance: 3,
36 | browserDisconnectTimeout : 300000,
37 | browserNoActivityTimeout : 300000,
38 |
39 | // web server port
40 | port: 8090,
41 | mochaReporter: {
42 | showDiff: true,
43 | output: 'autowatch'
44 | },
45 |
46 | // Start these browsers, currently available:
47 | // - Chrome
48 | // - ChromeCanary
49 | // - Firefox
50 | // - Opera
51 | // - Safari (only Mac)
52 | // - PhantomJS
53 | // - IE (only Windows)
54 | browsers: ['ChromeHeadless']
55 | })
56 | }
57 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "openhim-console",
3 | "description": "This application provides a web application to configure and manage the OpenHIM-core component.",
4 | "version": "1.18.3",
5 | "dependencies": {
6 | "http-server": "^14.1.1",
7 | "keycloak-js": "^20.0.3",
8 | "replace": "^1.2.2",
9 | "uuid": "^8.3.2"
10 | },
11 | "devDependencies": {
12 | "@babel/core": "^7.22.1",
13 | "@babel/polyfill": "^7.12.1",
14 | "@babel/preset-env": "^7.15.6",
15 | "@kariudo/angular-fullscreen": "^1.0.2",
16 | "@types/rimraf": "^3.0.2",
17 | "angular": "^1.8.3",
18 | "angular-bootstrap-colorpicker": "^3.0.32",
19 | "angular-cookies": "^1.8.2",
20 | "angular-file-upload": "^2.6.1",
21 | "angular-highlightjs": "^0.7.1",
22 | "angular-mocks": "^1.8.2",
23 | "angular-resource": "^1.8.2",
24 | "angular-route": "^1.8.2",
25 | "angular-sanitize": "^1.8.2",
26 | "angular-ui-bootstrap": "^2.5.0",
27 | "babel-loader": "^8.2.2",
28 | "bootstrap": "^3.4.1",
29 | "chai": "^4.3.7",
30 | "copy-webpack-plugin": "^6.4.1",
31 | "crypto-js": "^4.1.1",
32 | "css-loader": "^4.3.0",
33 | "d3": "^7.8.4",
34 | "dirty-chai": "^2.0.1",
35 | "eonasdan-bootstrap-datetimepicker": "^4.17.49",
36 | "file-loader": "^6.2.0",
37 | "file-saver": "^2.0.5",
38 | "html-loader": "^1.3.2",
39 | "html-webpack-plugin": "^4.5.2",
40 | "jquery": "^3.6.0",
41 | "json-loader": "^0.5.7",
42 | "karma": "^6.4.2",
43 | "karma-chrome-launcher": "^3.1.0",
44 | "karma-dirty-chai": "^2.0.0",
45 | "karma-mocha": "^2.0.1",
46 | "karma-mocha-reporter": "^2.2.5",
47 | "karma-sinon-chai": "^2.0.2",
48 | "lodash": "^4.17.21",
49 | "mini-css-extract-plugin": "^2.7.6",
50 | "mocha": "^10.2.0",
51 | "moment": "^2.29.4",
52 | "moment-timezone": "^0.5.43",
53 | "morris.js": "git+https://github.com/morrisjs/morris.js.git#77c24f6b70df2b23c7bd5d4d67240850d1b83005",
54 | "ng-file-upload": "^12.2.13",
55 | "pretty-data": "^0.40.0",
56 | "raphael": "^2.3.0",
57 | "rimraf": "^3.0.2",
58 | "sinon": "^9.2.4",
59 | "sinon-chai": "3.5.0",
60 | "speculate": "^2.1.1",
61 | "standard": "^17.0.0",
62 | "terser-webpack-plugin": "^4.2.3",
63 | "url-loader": "^4.1.1",
64 | "webpack": "^5.84.1",
65 | "webpack-bundle-analyzer": "^4.8.0",
66 | "webpack-cli": "^5.1.1",
67 | "webpack-dev-server": "^4.15.0",
68 | "webpack-merge": "^5.8.0",
69 | "webpack-sources": "^1.4.3"
70 | },
71 | "engines": {
72 | "node": ">=0.12.0"
73 | },
74 | "standard": {
75 | "globals": [
76 | "angular",
77 | "localStorage",
78 | "Blob",
79 | "sessionStorage",
80 | "FileReader",
81 | "$"
82 | ]
83 | },
84 | "spec": {
85 | "requires": [
86 | "nodejs"
87 | ],
88 | "environment": {
89 | "NODE_ENV": "production"
90 | },
91 | "post": [
92 | "npm install -g http-server"
93 | ]
94 | },
95 | "scripts": {
96 | "start": "http-server ./dist -p 9000",
97 | "start:dev": "webpack-dev-server --config webpack.development.js",
98 | "clean": "rimraf dist",
99 | "lint": "standard 'app/**/*.js'",
100 | "lint:fix": "npm run lint -- --fix",
101 | "test": "karma start --single-run",
102 | "test:watch": "karma start --auto-watch",
103 | "prepare": "npm run clean && npm run build:prod",
104 | "build": "webpack --config webpack.development.js",
105 | "build:prod": "NODE_OPTIONS=--max_old_space_size=4096 webpack --config webpack.production.js",
106 | "version": "node versionManager.js && git add -u",
107 | "spec": "speculate"
108 | },
109 | "repository": {
110 | "type": "git",
111 | "url": "https://github.com/jembi/openhim-console.git"
112 | },
113 | "keywords": [
114 | "openhim",
115 | "openhie"
116 | ],
117 | "author": "Jembi Health Systems NPC",
118 | "license": "MPL-2.0",
119 | "bugs": {
120 | "url": "https://github.com/jembi/openhim-console/issues"
121 | },
122 | "homepage": "http://openhim.org"
123 | }
124 |
--------------------------------------------------------------------------------
/packaging/README.md:
--------------------------------------------------------------------------------
1 | # Packaging OpenHIM Console
2 |
3 | ## Debian Packaging
4 |
5 | To create a debian package execute `./create-deb.sh`. This will run you through the process of creating a deb file. It can even upload a package to launchpad for inclusion in the ubuntu repositories if you so choose.
6 |
7 | To upload to launchpad you will have to have a public key create in gpg and registered with launchpad. You must link you .gnupg folder to the /packaging folder of this project for the upload to use it. From inside the /packaging folder execute `ln -s ~/.gnupg`.
8 |
9 | You must also have an environment variable set with the id of the key to use. View your keys with `gpg --list-keys` and export the id (the part after the '/') with `export DEB_SIGN_KEYID=xxx`. Now you should be all set to upload to launchpad. Use the following details when running the **./create-deb** script.
10 |
11 | Login: openhie
12 | PPA: release
13 |
14 | ## Bundled Release
15 |
16 | A bundled release will ensure all the relevant dependencies are downloaded and bundled into a built version of the OpenHIM console. Only the relevant scripts needed to run the OpenHIM console are added to the bundled release.
17 |
18 | To create a new build release execute the below command. This does assume that your Linux distribution has the `zip` and `tar` modules installed
19 |
20 | `./build-release-zip.sh
`
21 |
22 | E.g
23 |
24 | `./build-release-zip.sh v5.2.4`
25 |
26 | ## CentOS RPM Packaging
27 |
28 | Building the CentOS package makes uses of a CentOS docker container which runs various commands to build the package.
29 |
30 | Execute the `build-docker-centos-rpm.sh` bash script with a specific release version as an argument to build the RPM package on a specific release version.
31 |
32 | `build-docker-centos-rpm.sh 1.13.0-rc.1` will build and RPM package for the 1.13.0-rc.1 release of the OpenHIM Console
33 |
34 | Once the bash script has completed and cleaned up after itself, you will see the built rpm package in the directory of this script. The package will look something like:
35 | `openhim-console-1.13.0-rc.1-1.x86_64.rpm`
36 |
--------------------------------------------------------------------------------
/packaging/build-docker-centos-rpm.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | RELEASE_VERSION=$1
4 | if [ -z ${RELEASE_VERSION} ]
5 | then
6 | echo "You need so specify the release version you wish to build: e.g './build-docker-centos-rpm.sh 1.18.0'"
7 | echo "https://github.com/jembi/openhim-console/releases"
8 | exit
9 | fi
10 |
11 | # Set docker container name to build RPM package
12 | containerName=openhim-console-centos-rpm
13 |
14 | # Define the CentOS version to build in the docker container
15 | docker pull centos:7
16 |
17 | docker run -t -d --rm --name $containerName centos:7 /bin/bash
18 |
19 | echo "Update packages: "
20 | docker exec -it $containerName sh -c "yum -y update"
21 |
22 | echo "Install needed packages: "
23 | docker exec -it $containerName sh -c "yum install -y git rpm-build redhat-rpm-config gcc-c++ make"
24 |
25 | echo "Install needed packages: "
26 | docker exec -it $containerName sh -c "curl --silent --location https://rpm.nodesource.com/setup_14.x | bash -"
27 |
28 | echo "Install needed packages: "
29 | docker exec -it $containerName sh -c "yum install -y nodejs"
30 |
31 | echo "Fetch release version from Github"
32 | docker exec -it $containerName sh -c "mkdir /openhim-console && curl -sL 'https://github.com/jembi/openhim-console/archive/v$RELEASE_VERSION.tar.gz' | tar --strip-components=1 -zxv -C /openhim-console"
33 |
34 | echo "npm install && npm install speculate && npm run build"
35 | docker exec -it $containerName sh -c "cd /openhim-console && npm install && npm install speculate && npm run build:prod && npm run spec"
36 |
37 | echo "Symlink the openhim-console folder with the rpmbuild folder"
38 | docker exec -it $containerName sh -c "ln -s /openhim-console ~/rpmbuild"
39 |
40 | # if the Release Version incluldes a dash, apply workaround for rpmbuild to not break on dashes
41 | if [[ "${RELEASE_VERSION}" == *"-"* ]]
42 | then
43 | RELEASE_VERSION_TEMP=${RELEASE_VERSION//-/_}
44 | echo "Release Version contains unsupported dash (-) for building rpm package. Replacing with underscore (_) temporarily"
45 | docker exec -it $containerName sh -c "sed -i 's/$RELEASE_VERSION/$RELEASE_VERSION_TEMP/g' ~/rpmbuild/SPECS/openhim-console.spec"
46 | fi
47 |
48 | echo "Build RPM package from spec"
49 | docker exec -it $containerName sh -c "rpmbuild -bb ~/rpmbuild/SPECS/openhim-console.spec"
50 |
51 | # if the Release Version incluldes a dash, apply workaround for rpmbuild to not break on dashes
52 | if [[ "${RELEASE_VERSION}" == *"-"* ]]
53 | then
54 | RELEASE_VERSION_TEMP=${RELEASE_VERSION//-/_}
55 | echo "Rename the generated RPM package to the expected release version name (revert the changes from underscore to dashes)"
56 | docker exec -it $containerName sh -c "mv /openhim-console/RPMS/x86_64/openhim-console-$RELEASE_VERSION_TEMP-1.x86_64.rpm /openhim-console/RPMS/x86_64/openhim-console-$RELEASE_VERSION-1.x86_64.rpm"
57 | fi
58 |
59 | echo "Extract RPM package from container"
60 | docker cp $containerName:/openhim-console/RPMS/x86_64/openhim-console-$RELEASE_VERSION-1.x86_64.rpm .
61 |
62 | # Stop the container to ensure it gets cleaned up after running to commands
63 | echo "Removing the container"
64 | docker stop $containerName
65 |
--------------------------------------------------------------------------------
/packaging/build-release-zip.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -eu
4 |
5 | if (( $# < 1)); then
6 | echo "OpenHIM release build: Builds a specific tagged release ready for deployment";
7 | echo "Usage: $0 TAG";
8 | exit 0;
9 | fi
10 |
11 | tag=$1;
12 | shift;
13 |
14 | echo "NB!"
15 | echo "To create the tagged build, various git interactions need to take place. "
16 | echo "This will create a temporary branch as well as remove any changes you have havent yet committed"
17 | read -p "Do you wish to proceed? [y/N]" -n 1 -r
18 |
19 | echo ""
20 |
21 | if [[ $REPLY =~ ^[Yy]$ ]]; then
22 | cd ..
23 |
24 | echo "Git: setup branch/tag"
25 | git checkout -- .
26 | git checkout master
27 | git pull origin master
28 | git fetch --tags
29 | git checkout tags/$tag -b "build-release-$tag"
30 |
31 | echo "npm: clean and build package"
32 | rm -rf node_modules
33 | npm install
34 |
35 | echo "zip: build release version: $tag"
36 | cd dist/
37 | zip -r ../packaging/build.openhim-console.$tag.zip .
38 | tar -zcvf ../packaging/build.openhim-console.$tag.tar.gz .
39 | cd ..
40 |
41 | echo "Git cleanup"
42 | git checkout -- .
43 | git checkout master
44 | git branch -D "build-release-$tag"
45 |
46 | echo "New OpenHIM Console build zipped";
47 | fi
48 |
--------------------------------------------------------------------------------
/packaging/create-deb.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #Exit on error
3 | set -e
4 |
5 | CONSOLEDIR=/usr/share/openhim-console
6 |
7 | HOME=`pwd`
8 | AWK=/usr/bin/awk
9 | HEAD=/usr/bin/head
10 | DCH=/usr/bin/dch
11 |
12 | cd $HOME/targets
13 | TARGETS=(*)
14 | echo "Targets: $TARGETS"
15 | cd $HOME
16 |
17 | PKG=openhim-console
18 |
19 | echo -n "Which version of the OpenHIM-console (from github releases) would you like this package to install? (eg. 1.3.0) "
20 | read OPENHIM_VERSION
21 |
22 | echo -n "Would you like to upload the build(s) to Launchpad? [y/N] "
23 | read UPLOAD
24 | if [[ "$UPLOAD" == "y" || "$UPLOAD" == "Y" ]]; then
25 | if [ -n "$LAUNCHPADPPALOGIN" ]; then
26 | echo Using $LAUNCHPADPPALOGIN for Launchpad PPA login
27 | echo "To Change You can do: export LAUNCHPADPPALOGIN=$LAUNCHPADPPALOGIN"
28 | else
29 | echo -n "Enter your launchpad login for the ppa and press [ENTER]: "
30 | read LAUNCHPADPPALOGIN
31 | echo "You can do: export LAUNCHPADPPALOGIN=$LAUNCHPADPPALOGIN to avoid this step in the future"
32 | fi
33 |
34 | if [ -n "${DEB_SIGN_KEYID}" ]; then
35 | echo Using ${DEB_SIGN_KEYID} for Launchpad PPA login
36 | echo "To Change You can do: export DEB_SIGN_KEYID=${DEB_SIGN_KEYID}"
37 | echo "For unsigned you can do: export DEB_SIGN_KEYID="
38 | else
39 | echo "No DEB_SIGN_KEYID key has been set. Will create an unsigned"
40 | echo "To set a key for signing do: export DEB_SIGN_KEYID="
41 | echo "Use gpg --list-keys to see the available keys"
42 | fi
43 |
44 | echo -n "Enter the name of the PPA: "
45 | read PPA
46 | fi
47 |
48 |
49 | BUILDDIR=$HOME/builds
50 |
51 |
52 | for TARGET in "${TARGETS[@]}"
53 | do
54 | TARGETDIR=$HOME/targets/$TARGET
55 | RLS=`$HEAD -1 $TARGETDIR/debian/changelog | $AWK '{print $2}' | $AWK -F~ '{print $1}' | $AWK -F\( '{print $2}'`
56 | BUILDNO=$((${RLS##*-}+1))
57 |
58 | if [ -z "$BUILDNO" ]; then
59 | BUILDNO=1
60 | fi
61 |
62 | BUILD=${PKG}_${OPENHIM_VERSION}-${BUILDNO}~${TARGET}
63 | echo "Building $BUILD ..."
64 |
65 | # Update changelog
66 | cd $TARGETDIR
67 | echo "Updating changelog for build ..."
68 | $DCH -Mv "${OPENHIM_VERSION}-${BUILDNO}~${TARGET}" --distribution "${TARGET}" "Release Debian Build ${OPENHIM_VERSION}-${BUILDNO}. Find v${OPENHIM_VERSION} changelog here: https://github.com/jembi/openhim-console/releases"
69 |
70 | # Clear and create packaging directory
71 | PKGDIR=${BUILDDIR}/${BUILD}
72 | rm -fr $PKGDIR
73 | mkdir -p $PKGDIR
74 | cp -R $TARGETDIR/* $PKGDIR
75 |
76 | # Fetch openhim-console from github releases
77 | mkdir -p $PKGDIR$CONSOLEDIR
78 | wget -O /tmp/openhim-console.tar.gz https://github.com/jembi/openhim-console/releases/download/v${OPENHIM_VERSION}/openhim-console-v${OPENHIM_VERSION}.tar.gz
79 | tar -vxzf /tmp/openhim-console.tar.gz --directory $PKGDIR$CONSOLEDIR
80 |
81 | cd $PKGDIR
82 | if [[ "$UPLOAD" == "y" || "$UPLOAD" == "Y" ]] && [[ -n "${DEB_SIGN_KEYID}" && -n "{$LAUNCHPADLOGIN}" ]]; then
83 | echo "Uploading to PPA ${LAUNCHPADPPALOGIN}/${PPA}"
84 |
85 | CHANGES=${BUILDDIR}/${BUILD}_source.changes
86 |
87 | DPKGCMD="dpkg-buildpackage -k${DEB_SIGN_KEYID} -S -sa "
88 | $DPKGCMD
89 | DPUTCMD="dput ppa:$LAUNCHPADPPALOGIN/$PPA $CHANGES"
90 | $DPUTCMD
91 | else
92 | echo "Not uploading to launchpad"
93 | DPKGCMD="dpkg-buildpackage -uc -us"
94 | $DPKGCMD
95 | fi
96 | done
97 |
--------------------------------------------------------------------------------
/packaging/targets/trusty/debian/config:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . /usr/share/debconf/confmodule
4 |
5 | db_input critical openhim-console/selecthost || true
6 | db_input critical openhim-console/selectport || true
7 |
8 | db_go || true
9 |
--------------------------------------------------------------------------------
/packaging/targets/trusty/debian/control:
--------------------------------------------------------------------------------
1 | Source: openhim-console
2 | Maintainer: Ryan Crichton
3 | Section: web
4 | Priority: optional
5 | Standards-Version: 3.9.1
6 | Build-Depends: debhelper (>= 7)
7 | Homepage: https://github.com/openhie/openhim-console
8 |
9 |
10 | Package: openhim-console
11 | Architecture: all
12 | Depends: nginx, jq
13 | Recommends: openhim-core-js
14 | Description: The OpenHIM Console provides a web application to configure and manage the OpenHIM Core component. It provides the following features:
15 | -Configure and manage OpenHIM channels
16 | -View logged transactions
17 | -Configure clients that can access particular routes
18 | -Monitor the operations of the OpenHIM application
19 |
--------------------------------------------------------------------------------
/packaging/targets/trusty/debian/install:
--------------------------------------------------------------------------------
1 | /usr/share/openhim-console/*
2 | /etc/nginx/sites-available/*
3 |
--------------------------------------------------------------------------------
/packaging/targets/trusty/debian/postinst:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | CONSOLEDIR=/usr/share/openhim-console
5 | CONFIGFILE=$CONSOLEDIR/config/default.json
6 | ETCCONFIGFILE=/etc/openhim/console-config.json
7 |
8 | . /usr/share/debconf/confmodule
9 | db_get openhim-console/selecthost
10 | HOST=$RET
11 | db_get openhim-console/selectport
12 | PORT=$RET
13 |
14 | # Keep existing config file if there is one
15 | mkdir /etc/openhim || true
16 | if [ ! -f $ETCCONFIGFILE ]; then
17 | cp $CONFIGFILE $ETCCONFIGFILE
18 | else
19 | echo "Existing config file found, using that."
20 | fi
21 |
22 | # Replace the config with a link to a config in /etc/openhim/
23 | rm $CONFIGFILE
24 | ln -s $ETCCONFIGFILE $CONFIGFILE
25 |
26 | # Set host and port of openhim-core
27 | cat $ETCCONFIGFILE | jq 'to_entries | map(if .key == "host" then . + {"value": "'$HOST'"} else . end) | from_entries' > /tmp/config.json && mv /tmp/config.json $ETCCONFIGFILE
28 | cat $ETCCONFIGFILE | jq 'to_entries | map(if .key == "port" then . + {"value": "'$PORT'"} else . end) | from_entries' > /tmp/config.json && mv /tmp/config.json $ETCCONFIGFILE
29 |
30 | # Enable the openhim-console site in nginx
31 | ln -sf /etc/nginx/sites-available/openhim-console /etc/nginx/sites-enabled/
32 | # Disable the default site - can't have two sites on port 80 without server_name config
33 | rm -f /etc/nginx/sites-enabled/default
34 |
35 | service nginx reload
36 |
37 | echo "Successfully installed the OpenHIM-console!"
38 |
39 | exit 0
40 |
--------------------------------------------------------------------------------
/packaging/targets/trusty/debian/postrm:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | if [ "$1" = "purge" -a -e /usr/share/debconf/confmodule ]; then
5 | # Source debconf library.
6 | . /usr/share/debconf/confmodule
7 | # Remove my changes to the db.
8 | db_purge
9 | fi
10 |
--------------------------------------------------------------------------------
/packaging/targets/trusty/debian/rules:
--------------------------------------------------------------------------------
1 | #!/usr/bin/make -f
2 | # Uncomment this to turn on verbose mode.
3 | export DH_VERBOSE=1
4 |
5 | REVISION := $(shell head -1 debian/changelog | sed 's/.*(//;s/).*//;s/.*-//')
6 |
7 | build: build-stamp
8 | build-stamp:
9 | dh_testdir
10 | touch build-stamp
11 |
12 | clean:
13 | dh_testdir
14 | dh_testroot
15 | rm -f build-stamp
16 | dh_clean
17 |
18 | install: build
19 | dh_testdir
20 | dh_testroot
21 | dh_prep
22 | dh_installdirs
23 | dh_install
24 |
25 | # Build architecture-independent files here.
26 | binary-indep: build install
27 | dh_testdir
28 | dh_testroot
29 | dh_installchangelogs
30 | dh_installdocs
31 | dh_installdebconf
32 | dh_link
33 | dh_compress
34 | dh_fixperms
35 | dh_installdeb
36 | dh_gencontrol
37 | dh_md5sums
38 | dh_builddeb
39 |
40 | # Build architecture-dependent files here.
41 | binary-arch:
42 |
43 | binary: binary-indep binary-arch
44 | .PHONY: build clean binary-indep binary-arch binary install
--------------------------------------------------------------------------------
/packaging/targets/trusty/debian/templates:
--------------------------------------------------------------------------------
1 | Template: openhim-console/selecthost
2 | Type: string
3 | Default: localhost
4 | Description: What is the *public* hostname that the OpenHIM core server is running on?
5 |
6 | Template: openhim-console/selectport
7 | Type: string
8 | Default: 8080
9 | Description: What is the port that the OpenHIM core server API is running on?
10 |
--------------------------------------------------------------------------------
/packaging/targets/trusty/etc/nginx/sites-available/openhim-console:
--------------------------------------------------------------------------------
1 | # Site config for the OpenHIM-console
2 | server {
3 | root /usr/share/openhim-console;
4 | index index.html;
5 |
6 | location / {
7 | try_files $uri $uri/ =404;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/test/runner.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | End2end Test Runner
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/spec/controllers/about.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | 'use strict'
3 | /* jshint expr: true */
4 | /* global sinon: false */
5 |
6 | describe('Controller: AboutCtrl', function () {
7 | // load the controller's module
8 | beforeEach(module('openhimConsoleApp'))
9 |
10 | // setup config constant to be used for API server details
11 | beforeEach(function () {
12 | module('openhimConsoleApp', function ($provide) {
13 | $provide.constant('config', { version: '1.7.0', minimumCoreVersion: '3.0.0', protocol: 'https', host: 'localhost', hostPath: '', port: 8080, title: 'Title', footerTitle: 'FooterTitle', footerPoweredBy: 'FooterPoweredBy' })
14 | })
15 | })
16 |
17 | var scope, createController, httpBackend, modalSpy // eslint-disable-line
18 |
19 | var coreResponse = {
20 | currentCoreVersion: '3.0.0',
21 | serverTimeZone: 'Africa/Johannesburg'
22 | }
23 | var meResponse = {
24 | user: {
25 | email: 'test@user.org',
26 | firstname: 'test',
27 | surname: 'test',
28 | groups: [
29 | 'admin'
30 | ]
31 | }
32 | }
33 |
34 | // Initialize the controller and a mock scope
35 | beforeEach(inject(function ($controller, $rootScope, $httpBackend, $uibModal) {
36 | httpBackend = $httpBackend
37 |
38 | $httpBackend.when('GET', new RegExp('.*/about')).respond(coreResponse)
39 |
40 | modalSpy = sinon.spy($uibModal, 'open')
41 |
42 | createController = function () {
43 | $httpBackend.when('GET', new RegExp('.*/me')).respond(meResponse)
44 |
45 | scope = $rootScope.$new()
46 | return $controller('AboutCtrl', { $scope: scope })
47 | }
48 | }))
49 |
50 | afterEach(function () {
51 | httpBackend.verifyNoOutstandingExpectation()
52 | httpBackend.verifyNoOutstandingRequest()
53 | })
54 |
55 | it('should attach about information to the scope', function () {
56 | httpBackend.expectGET(new RegExp('.*/about'))
57 | createController()
58 | httpBackend.flush()
59 |
60 | scope.aboutInfo.currentConsoleVersion.should.equal('1.7.0')
61 | scope.aboutInfo.currentCoreVersion.should.equal('3.0.0')
62 |
63 | scope.aboutInfo.minimumCoreVersion.should.equal('3.0.0')
64 | scope.aboutInfo.maximumCoreVersion.should.equal('4.0.0')
65 | })
66 | })
67 |
--------------------------------------------------------------------------------
/test/spec/controllers/certificatesmodal.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | /* global sinon: false */
3 |
4 | describe('Controller: CertificatesModalCtrl', function () {
5 | // load the controller's module
6 | beforeEach(module('openhimConsoleApp'))
7 |
8 | // setup config constant to be used for API server details
9 | beforeEach(function () {
10 | module('openhimConsoleApp', function ($provide) {
11 | $provide.constant('config', { protocol: 'https', host: 'localhost', port: 8080, title: 'Title', footerTitle: 'FooterTitle', footerPoweredBy: 'FooterPoweredBy' })
12 | })
13 | })
14 |
15 | var scope, createController, httpBackend
16 | var meResponse = {
17 | user: {
18 | email: 'test@user.org',
19 | firstname: 'test',
20 | surname: 'test',
21 | groups: [
22 | 'admin'
23 | ]
24 | }
25 | }
26 |
27 | // Initialize the controller and a mock scope
28 | beforeEach(inject(function ($controller, $rootScope, $httpBackend) {
29 | httpBackend = $httpBackend
30 |
31 | $httpBackend.when('POST', new RegExp('.*/certificates')).respond(
32 | {
33 | certificate: '---BEGIN CERTIFICATE ---',
34 | key: '---BEGIN KEY ---'
35 | }
36 | )
37 |
38 | scope = $rootScope.$new()
39 | var modalInstance = sinon.spy()
40 |
41 | createController = function () {
42 | $httpBackend.when('GET', new RegExp('.*/me')).respond(meResponse)
43 | $httpBackend.flush()
44 |
45 | var cert
46 | cert = {
47 | $save: sinon.spy()
48 | }
49 | return $controller('CertificatesModalCtrl', {
50 | $scope: scope,
51 | $uibModalInstance: modalInstance,
52 | cert: cert,
53 | certType: 'client'
54 | })
55 | }
56 | }))
57 |
58 | afterEach(function () {
59 | httpBackend.verifyNoOutstandingExpectation()
60 | httpBackend.verifyNoOutstandingRequest()
61 | })
62 |
63 | it('should run validateFormCertificates() for any validation errors - ngErrors.hasErrors -> TRUE', function () {
64 | createController()
65 | scope.cert.commonName = ''
66 | scope.cert.days = ''
67 | scope.cert.country = ''
68 | // run the validate
69 | scope.validateFormCertificates()
70 | scope.ngError.should.have.property('commonName', true)
71 | scope.ngError.should.have.property('days', true)
72 | })
73 |
74 | it('should run validateFormCertificates() for any validation errors when the form is submitted - ngErrors.hasErrors -> TRUE', function () {
75 | createController()
76 | scope.cert.commonName = 'testCommonName'
77 | scope.cert.days = ''
78 | scope.cert.country = 'south africa'
79 | // run the
80 | scope.submitFormCertificate()
81 | scope.ngError.should.have.property('days', true)
82 | scope.ngError.should.have.property('country', true) // more than 2 letters
83 | })
84 |
85 | it('should generate the download links', function () {
86 | createController()
87 | scope.cert.commonName = 'testCommonName'
88 | scope.cert.days = '365'
89 | scope.cert.country = 'ZA'
90 | // submit the form
91 | scope.submitFormCertificate()
92 | // Generate the file Names
93 | scope.keyName.should.equal('testCommonName.key.pem')
94 | scope.certName.should.equal('testCommonName.cert.crt')
95 | httpBackend.flush()
96 | })
97 | })
98 |
--------------------------------------------------------------------------------
/test/spec/controllers/contactGroups.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | /* global sinon: false */
3 |
4 | describe('Controller: ContactGroupsCtrl', function () {
5 | // load the controller's module
6 | beforeEach(module('openhimConsoleApp'))
7 |
8 | // setup config constant to be used for API server details
9 | beforeEach(function () {
10 | module('openhimConsoleApp', function ($provide) {
11 | $provide.constant('config', { protocol: 'https', host: 'localhost', hostPath: '', port: 8080, title: 'Title', footerTitle: 'FooterTitle', footerPoweredBy: 'FooterPoweredBy' })
12 | })
13 | })
14 |
15 | var scope, createController, httpBackend, modalSpy
16 | var meResponse = {
17 | user: {
18 | email: 'test@user.org',
19 | firstname: 'test',
20 | surname: 'test',
21 | groups: [
22 | 'admin'
23 | ]
24 | }
25 | }
26 |
27 | // Initialize the controller and a mock scope
28 | beforeEach(inject(function ($controller, $rootScope, $httpBackend, $uibModal) {
29 | httpBackend = $httpBackend
30 |
31 | $httpBackend.when('GET', new RegExp('.*/groups')).respond([
32 | { group: 'Group 1', users: [{ user: 'User 1', method: 'sms', maxAlerts: 'no max' }] },
33 | { group: 'Group 2', users: [{ user: 'User 22', method: 'email', maxAlerts: 'no max' }] },
34 | { group: 'Group 3', users: [{ user: 'User 333', method: 'email', maxAlerts: '1 per hour' }] },
35 | { group: 'Group 4', users: [{ user: 'User 4444', method: 'sms', maxAlerts: '1 per day' }] }
36 | ])
37 |
38 | $httpBackend.when('GET', new RegExp('.*/users')).respond([
39 | { firstname: 'User1', lastname: 'User1111', email: 'user1@email.com' },
40 | { firstname: 'User22', lastname: 'User2222', email: 'user2@email.com' },
41 | { firstname: 'User333', lastname: 'User3333', email: 'user3@email.com' },
42 | { firstname: 'User4444', lastname: 'User4444', email: 'user4@email.com' }
43 | ])
44 |
45 | modalSpy = sinon.spy($uibModal, 'open')
46 |
47 | createController = function () {
48 | $httpBackend.when('GET', new RegExp('.*/me')).respond(meResponse)
49 |
50 | scope = $rootScope.$new()
51 | return $controller('ContactGroupsCtrl', { $scope: scope })
52 | }
53 | }))
54 |
55 | afterEach(function () {
56 | httpBackend.verifyNoOutstandingExpectation()
57 | httpBackend.verifyNoOutstandingRequest()
58 | })
59 |
60 | it('should attach a list of contact groups to the scope', function () {
61 | httpBackend.expectGET(new RegExp('.*/groups'))
62 | createController()
63 | httpBackend.flush()
64 | scope.contactGroups.length.should.equal(4)
65 | })
66 |
67 | it('should open a modal to confirm deletion of a client', function () {
68 | createController()
69 | httpBackend.flush()
70 |
71 | scope.confirmDelete(scope.contactGroups[0])
72 | modalSpy.should.have.been.calledOnce()
73 | })
74 |
75 | it('should open a modal to add a contact group', function () {
76 | createController()
77 | httpBackend.expectGET(new RegExp('.*/users'))
78 | scope.addContactGroup()
79 | modalSpy.should.have.been.calledOnce()
80 |
81 | httpBackend.flush()
82 | })
83 |
84 | it('should open a modal to edit a contact group', function () {
85 | createController()
86 | httpBackend.expectGET(new RegExp('.*/users'))
87 | scope.editContactGroup()
88 | modalSpy.should.have.been.calledOnce()
89 | httpBackend.flush()
90 | })
91 | })
92 |
--------------------------------------------------------------------------------
/test/spec/controllers/forgotPassword.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | describe('Controller: ForgotPasswordCtrl', function () {
4 | // load the controller's module
5 | beforeEach(module('openhimConsoleApp'))
6 |
7 | // setup config constant to be used for API server details
8 | beforeEach(function () {
9 | module('openhimConsoleApp', function ($provide) {
10 | $provide.constant('config', { protocol: 'https', host: 'localhost', hostPath: '', port: 8080, title: 'Title', footerTitle: 'FooterTitle', footerPoweredBy: 'FooterPoweredBy' })
11 | })
12 | })
13 |
14 | var scope, createController, httpBackend
15 |
16 | // Initialize the controller and a mock scope
17 | beforeEach(inject(function ($controller, $rootScope, $httpBackend) {
18 | httpBackend = $httpBackend
19 |
20 | $httpBackend.when('GET', new RegExp('.*/password-reset-request/test@test.com')).respond('Successfully set user token/expiry for password reset.')
21 | $httpBackend.when('GET', new RegExp('.*/password-reset-request/fake@email.com')).respond(404)
22 |
23 | createController = function () {
24 | // Shouldn't be authenticating when requesting for password reset
25 | httpBackend.when('GET', new RegExp('.*/me')).respond(404)
26 | httpBackend.flush()
27 |
28 | scope = $rootScope.$new()
29 | return $controller('ForgotPasswordCtrl', { $scope: scope })
30 | }
31 | }))
32 |
33 | afterEach(function () {
34 | httpBackend.verifyNoOutstandingExpectation()
35 | httpBackend.verifyNoOutstandingRequest()
36 | })
37 |
38 | it('should test that the controller loaded', function () {
39 | createController()
40 | scope.should.have.property('userEmail', '')
41 | scope.should.have.property('showFormCtrl', true)
42 | })
43 |
44 | it('should submit the form and return error for no email supplied', function () {
45 | createController()
46 | scope.should.have.property('userEmail', '')
47 | scope.should.have.property('showFormCtrl', true)
48 |
49 | scope.submitRequest()
50 |
51 | scope.alerts.should.have.property('forgotPassword')
52 | scope.alerts.forgotPassword[0].should.have.property('type', 'danger')
53 | scope.alerts.forgotPassword[0].should.have.property('msg', 'Please provide your email address')
54 | })
55 |
56 | it('should submit the form and return error for trying to reset "root@openhim.org"', function () {
57 | createController()
58 |
59 | scope.userEmail = 'root@openhim.org'
60 | scope.submitRequest()
61 |
62 | scope.alerts.should.have.property('forgotPassword')
63 | scope.alerts.forgotPassword[0].should.have.property('type', 'danger')
64 | scope.alerts.forgotPassword[0].should.have.property('msg', 'Cannot reset password for "root@openhim.org"')
65 | })
66 |
67 | it('should submit the form and return error for trying to reset an invalid email', function () {
68 | createController()
69 |
70 | scope.userEmail = 'fake@email.com'
71 | scope.submitRequest()
72 |
73 | scope.alerts.should.have.property('forgotPassword')
74 | scope.alerts.forgotPassword[0].should.have.property('type', 'warning')
75 | scope.alerts.forgotPassword[0].should.have.property('msg', 'Busy checking your credentials...')
76 |
77 | httpBackend.flush()
78 |
79 | scope.alerts.forgotPassword[0].should.have.property('type', 'danger')
80 | scope.alerts.forgotPassword[0].should.have.property('msg', 'Could not authenticate email address')
81 | })
82 |
83 | it('should submit the form and send a reset email to the user', function () {
84 | createController()
85 |
86 | scope.userEmail = 'test@test.com'
87 | scope.submitRequest()
88 |
89 | scope.alerts.should.have.property('forgotPassword')
90 | scope.alerts.forgotPassword[0].should.have.property('type', 'warning')
91 | scope.alerts.forgotPassword[0].should.have.property('msg', 'Busy checking your credentials...')
92 |
93 | httpBackend.flush()
94 |
95 | scope.alerts.forgotPassword[0].should.have.property('type', 'info')
96 | scope.alerts.forgotPassword[0].should.have.property('msg', 'Password reset email has been sent...')
97 | })
98 | })
99 |
--------------------------------------------------------------------------------
/test/spec/controllers/logs.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | describe('Controller: LogsCtrl', function () {
4 | // load the controller's module
5 | beforeEach(module('openhimConsoleApp'))
6 |
7 | // setup config constant to be used for API server details
8 | beforeEach(function () {
9 | module('openhimConsoleApp', function ($provide) {
10 | $provide.constant('config', { protocol: 'https', host: 'localhost', hostPath: '', port: 8080, title: 'Title', footerTitle: 'FooterTitle', footerPoweredBy: 'FooterPoweredBy' })
11 | })
12 | })
13 |
14 | var scope, createController, httpBackend, location, rootScope
15 | var meResponse = {
16 | user: {
17 | email: 'test@user.org',
18 | firstname: 'test',
19 | surname: 'test',
20 | groups: [
21 | 'admin'
22 | ]
23 | }
24 | }
25 |
26 | // Initialize the controller and a mock scope
27 | beforeEach(inject(function ($controller, $rootScope, $httpBackend, $location) {
28 | httpBackend = $httpBackend
29 | location = $location
30 | rootScope = $rootScope
31 |
32 | $httpBackend.when('GET', new RegExp('.*/logs')).respond([
33 | {
34 | label: 'worker1',
35 | meta: {},
36 | level: 'info',
37 | timestamp: '2015-10-29T09:40:31.536Z',
38 | message: 'Some message'
39 | },
40 | {
41 | label: 'worker1',
42 | meta: {},
43 | level: 'info',
44 | timestamp: '2015-10-29T09:40:39.128Z',
45 | message: 'Another message'
46 | }
47 | ])
48 |
49 | createController = function () {
50 | $httpBackend.when('GET', new RegExp('.*/me')).respond(meResponse)
51 |
52 | scope = $rootScope.$new()
53 | return $controller('LogsCtrl', { $scope: scope })
54 | }
55 | }))
56 |
57 | afterEach(function () {
58 | httpBackend.verifyNoOutstandingExpectation()
59 | httpBackend.verifyNoOutstandingRequest()
60 | })
61 |
62 | it('should fetch initial logs', function () {
63 | createController()
64 | httpBackend.flush()
65 |
66 | var logArr = scope.logs.split('\n')
67 | logArr[0].should.contain(' - info: [worker1] Some message')
68 | logArr[1].should.contain(' - info: [worker1] Another message')
69 | })
70 |
71 | it('should send data range in ISO 8601 format', function () {
72 | location.search({ level: 'debug', from: '2015-11-03 10:50', until: '2015-11-03 11:00' })
73 | httpBackend.when('GET', new RegExp('.*/me')).respond(meResponse)
74 | httpBackend.flush()
75 |
76 | rootScope.$apply()
77 |
78 | httpBackend.expectGET(new RegExp('.*/logs\\?from=2015-11-03T10:50:00.*&level=debug&until=2015-11-03T11:00:00.*'))
79 |
80 | createController()
81 | httpBackend.flush()
82 | })
83 |
84 | it('should reset the scope', function () {
85 | location.search({ level: 'debug', from: '2015-11-03 10:50', until: '2015-11-03 11:00' })
86 | httpBackend.when('GET', new RegExp('.*/me')).respond(meResponse)
87 | httpBackend.flush()
88 |
89 | rootScope.$apply()
90 |
91 | createController()
92 | httpBackend.flush()
93 | scope.reset()
94 |
95 | httpBackend.when('GET', new RegExp('.*/me')).respond(meResponse)
96 | httpBackend.flush()
97 |
98 | scope.params.level.should.equal('info')
99 | expect(scope.params.from).to.not.exist()
100 | expect(scope.params.until).to.not.exist()
101 | })
102 | })
103 |
--------------------------------------------------------------------------------
/test/spec/controllers/testAuditDetails.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | /* jshint expr: true */
3 | /* global sinon: false */
4 |
5 | describe('Controller: AuditDetailsCtrl', function () {
6 | // load the controller's module
7 | beforeEach(module('openhimConsoleApp'))
8 |
9 | // setup config constant to be used for API server details
10 | beforeEach(function () {
11 | module('openhimConsoleApp', function ($provide) {
12 | $provide.constant('config', { protocol: 'https', host: 'localhost', hostPath: '', port: 8080, title: 'Title', footerTitle: 'FooterTitle', footerPoweredBy: 'FooterPoweredBy' })
13 | })
14 | })
15 |
16 | var scope, createController, httpBackend, modalSpy // eslint-disable-line
17 | var meResponse = {
18 | user: {
19 | email: 'test@user.org',
20 | firstname: 'test',
21 | surname: 'test',
22 | groups: [
23 | 'admin'
24 | ]
25 | }
26 | }
27 |
28 | // Initialize the controller and a mock scope
29 | beforeEach(inject(function ($controller, $rootScope, $httpBackend, $uibModal) {
30 | httpBackend = $httpBackend
31 |
32 | $httpBackend.when('GET', new RegExp('.*/audits/538ed0867962a27d5df259b0')).respond({
33 | _id: '538ed0867962a27d5df259b0',
34 | rawMessage: 'This will be the raw ATNA message that gets received to be used as a backup reference',
35 | eventIdentification: {
36 | eventDateTime: '2015-02-17T15:38:25.282+02:00',
37 | eventOutcomeIndicator: '0',
38 | eventActionCode: 'R',
39 | eventID: { code: '222', displayName: 'Read', codeSystemName: 'DCM' },
40 | eventTypeCode: { code: 'ITI-9', displayName: 'PIX Read', codeSystemName: 'IHE Transactions' }
41 | },
42 | activeParticipant: [
43 | {
44 | userID: 'pix|pix',
45 | alternativeUserID: '2100',
46 | userIsRequestor: 'false',
47 | networkAccessPointID: 'localhost',
48 | networkAccessPointTypeCode: '1',
49 | roleIDCode: { code: '110152', displayName: 'Destination', codeSystemName: 'DCM' }
50 | }
51 | ],
52 | auditSourceIdentification: { auditSourceID: 'openhim' },
53 | participantObjectIdentification: [
54 | {
55 | participantObjectID: '975cac30-68e5-11e4-bf2a-04012ce65b02^^^ECID&ECID&ISO',
56 | participantObjectTypeCode: '1',
57 | participantObjectTypeCodeRole: '1',
58 | participantObjectIDTypeCode: { code: '2', displayName: 'PatientNumber', codeSystemName: 'RFC-3881' }
59 | }
60 | ]
61 | })
62 |
63 | $httpBackend.when('GET', new RegExp('.*/users/test@user.org')).respond({ _id: '539846c240f2eb682ffeca4b', email: 'test@user.org', firstname: 'test', surname: 'test', groups: ['admin', 'test', 'other'] })
64 |
65 | modalSpy = sinon.spy($uibModal, 'open')
66 |
67 | createController = function () {
68 | $httpBackend.when('GET', new RegExp('.*/me')).respond(meResponse)
69 |
70 | scope = $rootScope.$new()
71 | return $controller('AuditDetailsCtrl', { $scope: scope, $routeParams: { auditId: '538ed0867962a27d5df259b0' } })
72 | }
73 | }))
74 |
75 | afterEach(function () {
76 | httpBackend.verifyNoOutstandingExpectation()
77 | httpBackend.verifyNoOutstandingRequest()
78 | })
79 |
80 | it('should attach a single audit to the scope', function () {
81 | createController()
82 | httpBackend.flush()
83 | scope.auditDetails.eventIdentification.eventDateTime.should.equal('2015-02-17T15:38:25.282+02:00')
84 | scope.auditDetails.activeParticipant.length.should.equal(1)
85 | scope.auditDetails.activeParticipant[0].userID.should.equal('pix|pix')
86 | scope.auditDetails.auditSourceIdentification.auditSourceID.should.equal('openhim')
87 | scope.auditDetails.participantObjectIdentification.length.should.equal(1)
88 | })
89 | })
90 |
--------------------------------------------------------------------------------
/test/spec/controllers/transactionDetails.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | /* jshint expr: true */
3 | /* global sinon: false */
4 |
5 | describe('Controller: TransactionDetailsCtrl', function () {
6 | // load the controller's module
7 | beforeEach(module('openhimConsoleApp'))
8 |
9 | // setup config constant to be used for API server details
10 | beforeEach(function () {
11 | module('openhimConsoleApp', function ($provide) {
12 | $provide.constant('config', { protocol: 'https', host: 'localhost', hostPath: '', port: 8080, title: 'Title', footerTitle: 'FooterTitle', footerPoweredBy: 'FooterPoweredBy' })
13 | })
14 | })
15 |
16 | var scope, createController, httpBackend, modalSpy // eslint-disable-line
17 | var meResponse = {
18 | user: {
19 | email: 'test@user.org',
20 | firstname: 'test',
21 | surname: 'test',
22 | groups: [
23 | 'admin'
24 | ]
25 | }
26 | }
27 |
28 | // Initialize the controller and a mock scope
29 | beforeEach(inject(function ($controller, $rootScope, $httpBackend, $uibModal) {
30 | httpBackend = $httpBackend
31 |
32 | $httpBackend.when('GET', new RegExp('.*/transactions/538ed0867962a27d5df259b0')).respond({ _id: '5322fe9d8b6add4b2b059ff5', name: 'Transaction 1', urlPattern: 'sample/api', channelID: '5322fe9d8b6add4b2b059dd8', clientID: '5344fe7d8b6add4b2b069dd7' })
33 | $httpBackend.when('GET', new RegExp('.*/transactions?.*')).respond([{ name: 'Transaction 5', urlPattern: 'sample/api', _id: '5322fe9d8b6add4b2basd979', parentID: '5322fe9d8b6add4b2b059ff5' }])
34 |
35 | $httpBackend.when('GET', new RegExp('.*/users/test@user.org')).respond({ _id: '539846c240f2eb682ffeca4b', email: 'test@user.org', firstname: 'test', surname: 'test', groups: ['admin', 'test', 'other'] })
36 |
37 | $httpBackend.when('GET', new RegExp('.*/channels/5322fe9d8b6add4b2b059dd8')).respond({ _id: '5322fe9d8b6add4b2b059dd8', name: 'Sample JsonStub Channel 1', urlPattern: 'sample/api', allow: ['PoC'], txRerunAcl: ['test'], routes: [{ host: 'jsonstub.com', port: 80, primary: true }] })
38 |
39 | $httpBackend.when('GET', new RegExp('.*/clients/5344fe7d8b6add4b2b069dd7')).respond({ _id: '5344fe7d8b6add4b2b069dd7', clientID: 'test1', clientDomain: 'test1.openhim.org', name: 'Test 1', roles: ['test'], passwordAlgorithm: 'sha512', passwordHash: '1234', passwordSalt: '1234' })
40 |
41 | modalSpy = sinon.spy($uibModal, 'open')
42 |
43 | createController = function () {
44 | $httpBackend.when('GET', new RegExp('.*/me')).respond(meResponse)
45 |
46 | scope = $rootScope.$new()
47 | return $controller('TransactionDetailsCtrl', { $scope: scope, $routeParams: { transactionId: '538ed0867962a27d5df259b0' } })
48 | }
49 | }))
50 |
51 | afterEach(function () {
52 | httpBackend.verifyNoOutstandingExpectation()
53 | httpBackend.verifyNoOutstandingRequest()
54 | })
55 |
56 | it('should attach a single transaction to the scope', function () {
57 | createController()
58 | httpBackend.flush()
59 | scope.transactionDetails.name.should.equal('Transaction 1')
60 | scope.childTransactions.length.should.equal(1)
61 | })
62 |
63 | it('should attach a single channel object to the scope', function () {
64 | createController()
65 | httpBackend.flush()
66 |
67 | scope.channel.name.should.equal('Sample JsonStub Channel 1')
68 | scope.channel.urlPattern.should.equal('sample/api')
69 | scope.channel.routes.length.should.equal(1)
70 | })
71 |
72 | it('should attach a single client to the scope', function () {
73 | createController()
74 | httpBackend.flush()
75 |
76 | scope.client.name.should.equal('Test 1')
77 | scope.client.clientID.should.equal('test1')
78 | scope.client.clientDomain.should.equal('test1.openhim.org')
79 | scope.client.roles.length.should.equal(1)
80 | })
81 | })
82 |
--------------------------------------------------------------------------------
/test/spec/controllers/transactionsAddReqResModal.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | /* global sinon: false */
3 |
4 | describe('Controller: TransactionsAddReqResModalCtrl', function () {
5 | // load the controller's module
6 | beforeEach(module('openhimConsoleApp'))
7 |
8 | // setup config constant to be used for API server details
9 | beforeEach(function () {
10 | module('openhimConsoleApp', function ($provide) {
11 | $provide.constant('config', { protocol: 'https', host: 'localhost', hostPath: '', port: 8080, title: 'Title', footerTitle: 'FooterTitle', footerPoweredBy: 'FooterPoweredBy' })
12 | })
13 | })
14 |
15 | var scope, createController, modalInstance, record, channel
16 |
17 | // Initialize the controller and a mock scope
18 | beforeEach(inject(function ($controller, $rootScope) {
19 | createController = function () {
20 | record = {
21 | name: 'second',
22 | _id: '53df5d525b6d133c7de9eb56',
23 | response: {
24 | status: 301,
25 | body: 'this is dummy body content',
26 | timestamp: '2014-08-04T10:15:46.007Z'
27 | },
28 | request: {
29 | path: '/',
30 | querystring: '',
31 | method: 'GET'
32 | }
33 | }
34 |
35 | channel = {
36 | type: 'http'
37 | }
38 |
39 | scope = $rootScope.$new()
40 | modalInstance = sinon.spy()
41 | return $controller('TransactionsAddReqResModalCtrl', {
42 | $scope: scope,
43 | $uibModalInstance: modalInstance,
44 | record: record,
45 | channel: channel,
46 | transactionId: record._id,
47 | recordType: 'routes',
48 | index: 0
49 | })
50 | }
51 | }))
52 |
53 | it('should attach a single record object to the scope', function () {
54 | createController()
55 |
56 | scope.record.name.should.equal('second')
57 | scope.record.response.status.should.equal(301)
58 | scope.record.request.method.should.equal('GET')
59 | })
60 |
61 | it('should attach the channel object to the scope', function () {
62 | createController()
63 |
64 | scope.channel.type.should.equal('http')
65 | })
66 | })
67 |
--------------------------------------------------------------------------------
/test/spec/services/authinterceptor.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | /* global CryptoJS: false */
3 |
4 | describe('Service: Authinterceptor', function () {
5 | // load the service's module
6 | beforeEach(module('openhimConsoleApp'))
7 |
8 | // setup config constant to be used for API server details
9 | beforeEach(function () {
10 | module('openhimConsoleApp', function ($provide) {
11 | $provide.constant('config', { protocol: 'https', host: 'localhost', port: 8080, title: 'Title', footerTitle: 'FooterTitle', footerPoweredBy: 'FooterPoweredBy' })
12 | })
13 | })
14 |
15 | // instantiate service
16 | var Authinterceptor, location
17 | beforeEach(inject(function (_Authinterceptor_, $location) {
18 | Authinterceptor = _Authinterceptor_
19 | location = $location
20 | }))
21 |
22 | it('should redirect to login page if not authorised', function () {
23 | var response = {
24 | status: 401
25 | }
26 | Authinterceptor.responseError(response)
27 | var currentLocation = location.path();
28 | currentLocation.should.be.equal('/login')
29 | })
30 | })
31 |
--------------------------------------------------------------------------------
/test/spec/services/login.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | describe('Service: login', function () {
4 | // load the service's module
5 | beforeEach(module('openhimConsoleApp'))
6 |
7 | // setup config constant to be used for API server details
8 | beforeEach(function () {
9 | module('openhimConsoleApp', function ($provide) {
10 | $provide.constant('config', { protocol: 'https', host: 'localhost', port: 8080, title: 'Title', footerTitle: 'FooterTitle', footerPoweredBy: 'FooterPoweredBy' })
11 | })
12 | })
13 |
14 | // instantiate service
15 | var login, httpBackend
16 | beforeEach(inject(function (_login_, $httpBackend) {
17 | login = _login_
18 |
19 | httpBackend = $httpBackend
20 |
21 | httpBackend.when('GET', new RegExp('.*/me')).respond(404)
22 |
23 | httpBackend.when('POST', new RegExp('.*/authenticate/local')).respond({
24 | body: "User Authenticated successfully"
25 | })
26 |
27 | httpBackend.when('GET', new RegExp('.*/users/.*')).respond({
28 | __v: 0,
29 | _id: '539846c240f2eb682ffeca4b',
30 | email: 'test@user.org',
31 | firstname: 'test',
32 | surname: 'test',
33 | groups: [
34 | 'admin'
35 | ]
36 | })
37 |
38 | httpBackend.when('GET', new RegExp('.*/logout')).respond(201)
39 | }))
40 |
41 | afterEach(function () {
42 | httpBackend.verifyNoOutstandingExpectation()
43 | httpBackend.verifyNoOutstandingRequest()
44 | })
45 |
46 | it('should login a user and fetch the currently logged in user', function () {
47 | httpBackend.expectPOST(new RegExp('.*/authenticate/local'))
48 | httpBackend.expectGET(new RegExp('.*/users/test@user.org'))
49 |
50 | login.login('test@user.org', 'test-password', function () {})
51 | httpBackend.flush()
52 |
53 | var user = login.getLoggedInUser()
54 |
55 | user.should.exist()
56 | user.should.have.property('email', 'test@user.org')
57 | })
58 |
59 | it('should logout a user', function () {
60 | httpBackend.expectGET(new RegExp('.*/logout'))
61 |
62 | login.logout(function () {})
63 | httpBackend.flush()
64 |
65 | var user = login.getLoggedInUser()
66 | expect((user === null)).to.be.true()
67 | expect(login.isLoggedIn()).to.be.false()
68 | })
69 |
70 | it('should check if a user is currently logged in', function () {
71 | httpBackend.flush()
72 | expect(login.isLoggedIn()).to.be.false()
73 |
74 | login.login('test@user.org', 'test-password', function () {})
75 | httpBackend.flush()
76 |
77 | expect(login.isLoggedIn()).to.be.true()
78 |
79 | login.logout(function () {})
80 | httpBackend.flush()
81 |
82 | expect(login.isLoggedIn()).to.be.false()
83 | })
84 | })
85 |
--------------------------------------------------------------------------------
/test/spec/services/notify.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | /* global sinon:false */
3 |
4 | describe('Service: Notify', function () {
5 | // load the service's module
6 | beforeEach(module('openhimConsoleApp'))
7 |
8 | // setup config constant to be used for API server details
9 | beforeEach(function () {
10 | module('openhimConsoleApp', function ($provide) {
11 | $provide.constant('config', { protocol: 'https', host: 'localhost', port: 8080, title: 'Title', footerTitle: 'FooterTitle', footerPoweredBy: 'FooterPoweredBy' })
12 | })
13 | })
14 |
15 | // instantiate service
16 | var Notify
17 | var rootScope
18 | beforeEach(inject(function (_Notify_, $rootScope) {
19 | Notify = _Notify_
20 | rootScope = $rootScope
21 | sinon.spy(rootScope, '$broadcast')
22 | }))
23 |
24 | it('should broadcast an event', function () {
25 | Notify.should.be.ok()
26 | Notify.notify('testEvent')
27 | rootScope.$broadcast.should.have.been.calledWith('testEvent')
28 | })
29 | })
30 |
--------------------------------------------------------------------------------
/test/spec/services/rest.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | describe('Service: Api', function () {
4 | // load the service's module
5 | beforeEach(module('openhimConsoleApp'))
6 |
7 | // setup config constant to be used for API server details
8 | beforeEach(function () {
9 | module('openhimConsoleApp', function ($provide) {
10 | $provide.constant('config', { protocol: 'https', host: 'localhost', port: 8080, title: 'Title', footerTitle: 'FooterTitle', footerPoweredBy: 'FooterPoweredBy' })
11 | })
12 | })
13 |
14 | // instantiate service
15 | var Api
16 | beforeEach(inject(function (_Api_) {
17 | Api = _Api_
18 | }))
19 |
20 | it('should define an Api service', function () {
21 | Api.should.be.ok()
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/versionManager.js:
--------------------------------------------------------------------------------
1 | var currentConsoleVersion = require('./package.json').version
2 | var https = require('https')
3 | var replace = require('replace')
4 |
5 | // Get latest version of core from Github
6 | var options = {
7 | protocol: 'https:',
8 | hostname: 'github.com',
9 | path: '/jembi/openhim-core-js/releases/latest',
10 | method: 'GET'
11 | }
12 |
13 | var replaceStringInline = function (inlineRegex, replacement, paths) {
14 | replace({
15 | regex: inlineRegex,
16 | replacement: replacement,
17 | paths: paths,
18 | recursive: true,
19 | silent: true
20 | })
21 | }
22 |
23 | var req = https.request(options, function (res) {
24 | var data = ''
25 | res.setEncoding('utf8')
26 |
27 | res.on('data', (chunk) => {
28 | data += chunk
29 | })
30 |
31 | res.on('end', () => {
32 | var minimumCoreVersion = data.split('releases/tag/v')[1].substring(0, 5)
33 | // Add latest version of core to console config
34 | replaceStringInline(/"minimumCoreVersion":"[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}"/, `"minimumCoreVersion": "${minimumCoreVersion}"`, ['./app/config/default.json'])
35 | // Edit readme with compatible version of core
36 | replaceStringInline(/badge\/openhim--core-[0-9]{1,2}\.[0-9]{1,2}/, `badge/openhim--core-${minimumCoreVersion.substr(0, 3)}`, ['README.md'])
37 | replaceStringInline(/openhim.readthedocs.org\/en\/v[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}/, `openhim.readthedocs.org/en/v${minimumCoreVersion}`, ['README.md'])
38 | })
39 | })
40 |
41 | req.on('error', (e) => {
42 | console.log(`Problem fetching core version from github: ${e.message}`)
43 | })
44 |
45 | req.end()
46 |
47 | // Keep version of console consistent throughout project
48 | replaceStringInline(/"version":"[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}"/, `"version": "${currentConsoleVersion}"`, ['./app/config/default.json'])
49 | replaceStringInline(/"version":"[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}"/, `"version": "${currentConsoleVersion}"`, ['./.travis/test.json'])
50 | replaceStringInline(/"version":"[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}"/, `"version": "${currentConsoleVersion}"`, ['./.travis/staging.json'])
51 |
--------------------------------------------------------------------------------
/webpack.common.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const path = require('path')
4 | const webpack = require('webpack')
5 | const HtmlWebpackPlugin = require('html-webpack-plugin')
6 | const CopyWebpackPlugin = require('copy-webpack-plugin')
7 | const MiniCssExtractPlugin = require('mini-css-extract-plugin')
8 |
9 | module.exports = {
10 | entry: './app/scripts/index',
11 | output: {
12 | path: path.resolve(__dirname, 'dist'),
13 | filename: 'bundle.js'
14 | },
15 | resolve: {
16 | extensions: ['.js', '.json', '.jsx', '.css', '.html'],
17 | alias: {
18 | 'morris.js': path.resolve(__dirname, 'node_modules/morris.js/morris.js'),
19 | '~': path.resolve(__dirname, 'app')
20 | }
21 | },
22 | target: 'web',
23 | module: {
24 | rules: [
25 | {
26 | test: /\.(ttf|eot|woff|woff2|svg)$/,
27 | loader: 'file-loader',
28 | options: {
29 | name: 'fonts/[name].[ext]'
30 | }
31 | },
32 | {
33 | test: /\.(png|jpg|gif)$/,
34 | use: [
35 | {
36 | loader: 'url-loader',
37 | options: {
38 | limit: 8192
39 | }
40 | }
41 | ]
42 | },
43 | {
44 | test: /\.m?js$/,
45 | exclude: /(node_modules|bower_components)/,
46 | include: [path.resolve(__dirname, 'app')],
47 | use: {
48 | loader: 'babel-loader',
49 | options: {
50 | presets: ['@babel/preset-env']
51 | }
52 | }
53 | }
54 | ]
55 | },
56 | plugins: [
57 | new webpack.ProvidePlugin({
58 | $: 'jquery',
59 | jQuery: 'jquery',
60 | 'window.jQuery': 'jquery'
61 | }),
62 | new HtmlWebpackPlugin({
63 | template: 'app/template.html'
64 | }),
65 | new MiniCssExtractPlugin({
66 | filename: 'styles.css'
67 | }),
68 | new CopyWebpackPlugin({patterns: [
69 | { from: 'app/404.html' },
70 | { from: 'app/favicon.ico' },
71 | { from: 'app/robots.txt' },
72 | {
73 | context: 'app/config',
74 | from: '*',
75 | to: 'config/'
76 | }
77 | ]})]
78 | }
79 |
--------------------------------------------------------------------------------
/webpack.development.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const { merge } = require('webpack-merge')
4 | const common = require('./webpack.common.js')
5 | const path = require('path')
6 | const MiniCssExtractPlugin = require('mini-css-extract-plugin')
7 |
8 | console.log('Creating development bundle')
9 |
10 | module.exports = merge(common, {
11 | mode: 'development',
12 | module: {
13 | rules: [
14 | {
15 | test: /\.html$/,
16 | include: [path.resolve(__dirname, 'app')],
17 | use: [
18 | {
19 | loader: 'html-loader',
20 | options: {
21 | minimize: false
22 | }
23 | }
24 | ]
25 | },
26 | {
27 | test: /\.css$/,
28 | use: [
29 | {
30 | loader: MiniCssExtractPlugin.loader,
31 | options: {}
32 | },
33 | 'css-loader'
34 | ]
35 | }
36 | ]
37 | },
38 | devtool: 'source-map',
39 | devServer: {
40 | static: path.resolve(__dirname, 'app'),
41 | port: 9000,
42 | open: true,
43 | hot: true
44 | }
45 | })
46 |
--------------------------------------------------------------------------------
/webpack.production.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const { merge } = require('webpack-merge')
4 | const common = require('./webpack.common.js')
5 |
6 | const path = require('path')
7 | const MiniCssExtractPlugin = require('mini-css-extract-plugin')
8 | const TerserPlugin = require('terser-webpack-plugin')
9 |
10 | console.log('Creating production bundle')
11 |
12 | module.exports = merge(common, {
13 | mode: 'production',
14 | optimization: {
15 | minimizer: [
16 | new TerserPlugin({
17 | terserOptions: {
18 | mangle: false
19 | }
20 | })
21 | ]
22 | },
23 | module: {
24 | rules: [
25 | {
26 | test: /\.html$/,
27 | include: [path.resolve(__dirname, 'app')],
28 | use: [
29 | {
30 | loader: 'html-loader',
31 | options: {
32 | minimize: true
33 | }
34 | }
35 | ]
36 | },
37 | {
38 | test: /\.css$/,
39 | use: [
40 | {
41 | loader: MiniCssExtractPlugin.loader
42 | },
43 | 'css-loader'
44 | ]
45 | }
46 | ]
47 | }
48 | })
49 |
--------------------------------------------------------------------------------