├── .gitignore ├── html ├── css │ └── main.css ├── assets │ ├── DataTables │ │ └── 1.10.15 │ │ │ ├── images │ │ │ ├── sort_asc.png │ │ │ ├── sort_both.png │ │ │ ├── sort_desc.png │ │ │ ├── sort_asc_disabled.png │ │ │ └── sort_desc_disabled.png │ │ │ └── css │ │ │ └── jquery.dataTables.css │ └── font-awesome │ │ └── 4.7.0 │ │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ │ ├── less │ │ ├── screen-reader.less │ │ ├── fixed-width.less │ │ ├── larger.less │ │ ├── list.less │ │ ├── core.less │ │ ├── stacked.less │ │ ├── font-awesome.less │ │ ├── bordered-pulled.less │ │ ├── rotated-flipped.less │ │ ├── path.less │ │ ├── animated.less │ │ └── mixins.less │ │ ├── scss │ │ ├── _fixed-width.scss │ │ ├── _screen-reader.scss │ │ ├── _larger.scss │ │ ├── _list.scss │ │ ├── _core.scss │ │ ├── font-awesome.scss │ │ ├── _stacked.scss │ │ ├── _bordered-pulled.scss │ │ ├── _rotated-flipped.scss │ │ ├── _path.scss │ │ ├── _animated.scss │ │ └── _mixins.scss │ │ └── HELP-US-OUT.txt ├── logout.php ├── logs.php ├── users.php ├── index.php ├── api.php ├── view-contact.php ├── login.php ├── delete-api.php ├── delete-contact.php ├── add-api.php ├── delete-user.php ├── update-api.php ├── add-user.php ├── add-contact.php └── update-user.php ├── screenshots ├── api-delete.png ├── api-table.png ├── api-update.png ├── logs-table.png ├── users-add.png ├── users-table.png ├── contacts-add.png ├── contacts-view.png ├── users-delete.png ├── users-update.png ├── api-call-success.png ├── contacts-delete.png ├── contacts-table.png └── contacts-update.png ├── docker ├── PHP-FPM.Dockerfile └── nginx.conf ├── includes ├── layout.footer.inc.php ├── class.redirect.inc.php ├── functions.inc.php ├── class.db.inc.php ├── layout.head.inc.php ├── EXAMPLE.settings.local.inc.php ├── layout.navigation.inc.php ├── class.csrf.inc.php ├── class.session.inc.php ├── alerts.validation.inc.php ├── alerts.notification.inc.php ├── settings.config.inc.php ├── class.log.inc.php ├── class.contact.inc.php └── class.api.inc.php ├── docker-compose.yml ├── LICENSE.md ├── CHANGELOG.md ├── SCREENSHOTS.md ├── sql └── sql.sql └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | includes/settings.local.inc.php 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /html/css/main.css: -------------------------------------------------------------------------------- 1 | .pt-15 { 2 | padding-top: 15px; 3 | } 4 | .pt-50 { 5 | padding-top: 50px; 6 | } -------------------------------------------------------------------------------- /screenshots/api-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/screenshots/api-delete.png -------------------------------------------------------------------------------- /screenshots/api-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/screenshots/api-table.png -------------------------------------------------------------------------------- /screenshots/api-update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/screenshots/api-update.png -------------------------------------------------------------------------------- /screenshots/logs-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/screenshots/logs-table.png -------------------------------------------------------------------------------- /screenshots/users-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/screenshots/users-add.png -------------------------------------------------------------------------------- /screenshots/users-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/screenshots/users-table.png -------------------------------------------------------------------------------- /screenshots/contacts-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/screenshots/contacts-add.png -------------------------------------------------------------------------------- /screenshots/contacts-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/screenshots/contacts-view.png -------------------------------------------------------------------------------- /screenshots/users-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/screenshots/users-delete.png -------------------------------------------------------------------------------- /screenshots/users-update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/screenshots/users-update.png -------------------------------------------------------------------------------- /screenshots/api-call-success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/screenshots/api-call-success.png -------------------------------------------------------------------------------- /screenshots/contacts-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/screenshots/contacts-delete.png -------------------------------------------------------------------------------- /screenshots/contacts-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/screenshots/contacts-table.png -------------------------------------------------------------------------------- /screenshots/contacts-update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/screenshots/contacts-update.png -------------------------------------------------------------------------------- /docker/PHP-FPM.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:8.4-fpm 2 | 3 | RUN docker-php-ext-install pdo pdo_mysql 4 | RUN docker-php-ext-enable pdo pdo_mysql -------------------------------------------------------------------------------- /html/assets/DataTables/1.10.15/images/sort_asc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/html/assets/DataTables/1.10.15/images/sort_asc.png -------------------------------------------------------------------------------- /html/assets/DataTables/1.10.15/images/sort_both.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/html/assets/DataTables/1.10.15/images/sort_both.png -------------------------------------------------------------------------------- /html/assets/DataTables/1.10.15/images/sort_desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/html/assets/DataTables/1.10.15/images/sort_desc.png -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/html/assets/font-awesome/4.7.0/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /html/assets/DataTables/1.10.15/images/sort_asc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/html/assets/DataTables/1.10.15/images/sort_asc_disabled.png -------------------------------------------------------------------------------- /html/assets/DataTables/1.10.15/images/sort_desc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/html/assets/DataTables/1.10.15/images/sort_desc_disabled.png -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/html/assets/font-awesome/4.7.0/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/html/assets/font-awesome/4.7.0/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/html/assets/font-awesome/4.7.0/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexWinder/address-book/HEAD/html/assets/font-awesome/4.7.0/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/less/screen-reader.less: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { .sr-only(); } 5 | .sr-only-focusable { .sr-only-focusable(); } 6 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/less/fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/scss/_screen-reader.scss: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { @include sr-only(); } 5 | .sr-only-focusable { @include sr-only-focusable(); } 6 | -------------------------------------------------------------------------------- /docker/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | root /var/www/html/html; 4 | 5 | index index.php; 6 | 7 | charset utf-8; 8 | 9 | location ~ \.php$ { 10 | fastcgi_pass php-fpm:9000; 11 | fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; 12 | include fastcgi_params; 13 | } 14 | } -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/HELP-US-OUT.txt: -------------------------------------------------------------------------------- 1 | I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project, 2 | Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome, 3 | comprehensive icon sets or copy and paste your own. 4 | 5 | Please. Check it out. 6 | 7 | -Dave Gandy 8 | -------------------------------------------------------------------------------- /includes/layout.footer.inc.php: -------------------------------------------------------------------------------- 1 | 2 | 7 | $(document).ready( function () { 8 | $('#{$datatables_table_id}').DataTable( { 9 | {$datatables_option} 10 | } ); 11 | } ); 12 | 13 | 14 | FILEDOC; 15 | echo $datatable_script; 16 | }; 17 | ?> 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/less/larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .@{fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .@{fa-css-prefix}-2x { font-size: 2em; } 11 | .@{fa-css-prefix}-3x { font-size: 3em; } 12 | .@{fa-css-prefix}-4x { font-size: 4em; } 13 | .@{fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .#{$fa-css-prefix}-2x { font-size: 2em; } 11 | .#{$fa-css-prefix}-3x { font-size: 3em; } 12 | .#{$fa-css-prefix}-4x { font-size: 4em; } 13 | .#{$fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /includes/class.redirect.inc.php: -------------------------------------------------------------------------------- 1 | li { position: relative; } 9 | } 10 | .@{fa-css-prefix}-li { 11 | position: absolute; 12 | left: -@fa-li-width; 13 | width: @fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.@{fa-css-prefix}-lg { 17 | left: (-@fa-li-width + (4em / 14)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/less/core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "animated"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | @import "screen-reader"; 19 | -------------------------------------------------------------------------------- /html/logout.php: -------------------------------------------------------------------------------- 1 | authenticated) { 10 | $user->logout('not_authenticated'); 11 | }; 12 | 13 | // Create new Log instance, and log the action to the database 14 | $log = new Log('logout_success'); 15 | 16 | // Log the user out 17 | $user->logout(); 18 | 19 | ?> -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/less/stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 21 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables.less"; 7 | @import "mixins.less"; 8 | @import "path.less"; 9 | @import "core.less"; 10 | @import "larger.less"; 11 | @import "fixed-width.less"; 12 | @import "list.less"; 13 | @import "bordered-pulled.less"; 14 | @import "animated.less"; 15 | @import "rotated-flipped.less"; 16 | @import "stacked.less"; 17 | @import "icons.less"; 18 | @import "screen-reader.less"; 19 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/less/bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em @fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .@{fa-css-prefix}-pull-left { float: left; } 11 | .@{fa-css-prefix}-pull-right { float: right; } 12 | 13 | .@{fa-css-prefix} { 14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | 18 | /* Deprecated as of 4.4.0 */ 19 | .pull-right { float: right; } 20 | .pull-left { float: left; } 21 | 22 | .@{fa-css-prefix} { 23 | &.pull-left { margin-right: .3em; } 24 | &.pull-right { margin-left: .3em; } 25 | } 26 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/scss/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em $fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .#{$fa-css-prefix}-pull-left { float: left; } 11 | .#{$fa-css-prefix}-pull-right { float: right; } 12 | 13 | .#{$fa-css-prefix} { 14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | 18 | /* Deprecated as of 4.4.0 */ 19 | .pull-right { float: right; } 20 | .pull-left { float: left; } 21 | 22 | .#{$fa-css-prefix} { 23 | &.pull-left { margin-right: .3em; } 24 | &.pull-right { margin-left: .3em; } 25 | } 26 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/less/rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .@{fa-css-prefix}-rotate-90, 15 | :root .@{fa-css-prefix}-rotate-180, 16 | :root .@{fa-css-prefix}-rotate-270, 17 | :root .@{fa-css-prefix}-flip-horizontal, 18 | :root .@{fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .#{$fa-css-prefix}-rotate-90, 15 | :root .#{$fa-css-prefix}-rotate-180, 16 | :root .#{$fa-css-prefix}-rotate-270, 17 | :root .#{$fa-css-prefix}-flip-horizontal, 18 | :root .#{$fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | nginx: 3 | image: nginx:latest 4 | volumes: 5 | - ./docker/nginx.conf:/etc/nginx/conf.d/default.conf 6 | - ./:/var/www/html 7 | ports: 8 | - 80:80 9 | depends_on: 10 | - php-fpm 11 | - mysql 12 | php-fpm: 13 | build: 14 | context: docker 15 | dockerfile: PHP-FPM.Dockerfile 16 | volumes: 17 | - ./:/var/www/html 18 | mysql: 19 | image: mysql:9 20 | volumes: 21 | - 'address-book-db:/var/lib/mysql' 22 | - ./sql/sql.sql:/docker-entrypoint-initdb.d/initialise.sql 23 | environment: 24 | - MYSQL_RANDOM_ROOT_PASSWORD=yes 25 | 26 | volumes: 27 | address-book-db: 28 | driver: local -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/less/path.less: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}'); 7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'), 8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'), 9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'), 10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'), 11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg'); 12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/scss/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); 7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), 8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'), 9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), 10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), 11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); 12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | -------------------------------------------------------------------------------- /includes/functions.inc.php: -------------------------------------------------------------------------------- 1 | getMessage(); 22 | } 23 | } 24 | // Return the Singleton $instance 25 | return self::$instance; 26 | } 27 | 28 | }; // Close class DB 29 | 30 | // EOF -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Alex Winder 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /includes/layout.head.inc.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <?php echo page_name(); ?> 5 | 6 | 7 | 8 | 13 | 14 | 15 | 16 | FILEDOC; 17 | echo $datatables_source; 18 | }; 19 | ?> 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Address Book Changelog 2 | 3 | ## 1.0.6 (2025-03-28) 4 | 5 | - Docker PHP support updated version `8.4` ([#8](https://github.com/AlexWinder/address-book/issues/8)). 6 | - Docker MySQL support updated to version `9`. 7 | - Fixed incorrect redirect to index page after creating a new user. 8 | 9 | ## 1.0.5 (2025-01-05) 10 | 11 | - Added timezone support by [@zaydons](https://github.com/zaydons) in https://github.com/AlexWinder/address-book/pull/6. 12 | 13 | ## 1.0.4 (2022-08-03) 14 | 15 | - Updated README to include support for `docker compose` on top of `docker-compose`. 16 | - Fixed README with a typo on the `DB_PASS` value. 17 | - API calls returned with the correct header of `Content-Type: application/json`. 18 | - API calls returned with the correct HTTP status code rather than all being returned as HTTP 200 OK. 19 | 20 | ## 1.0.3 (2022-07-17) 21 | 22 | - Added Docker build environment. 23 | - Updated README file instructions and markdown formatting. 24 | 25 | ## 1.0.2 (2020-04-30) 26 | 27 | - Updated jQuery to 3.5.0 to address [CVE-2020-11022](https://github.com/advisories/GHSA-gxr4-xjj5-5px2). 28 | - Updated Bootstrap to 3.4.1. 29 | 30 | ## 1.0.1 (2019-12-26) 31 | 32 | - Added missing DataTables sort images. 33 | - Added missing Bootstrap map files. 34 | - Fixed Bootstrap directory name causing issues on some browsers not loading assets. 35 | 36 | ## 1.0.0 (2018-05-24) 37 | 38 | - Initial release of system. 39 | -------------------------------------------------------------------------------- /SCREENSHOTS.md: -------------------------------------------------------------------------------- 1 | # Contacts System 2 | 3 | ## Contacts table 4 | ![Table of contacts](screenshots/contacts-table.png?raw=true "Contacts presented in HTML table") 5 | 6 | ## View contact 7 | ![View contact details](screenshots/contacts-view.png?raw=true "Contact details presented in a HTML page") 8 | 9 | ## Add contact 10 | ![Add contact form](screenshots/contacts-add.png?raw=true "HTML form for adding a contact") 11 | 12 | ## Delete contact 13 | ![Delete contact form](screenshots/contacts-delete.png?raw=true "HTML form for deleting a contact") 14 | 15 | ## Update contact 16 | ![Update contact form](screenshots/contacts-update.png?raw=true "HTML form for updating a contact") 17 | 18 | # Users 19 | 20 | ## Users table 21 | ![Table of users](screenshots/users-table.png?raw=true "Users presented in HTML table") 22 | 23 | ## Add user 24 | ![Add user form](screenshots/users-add.png?raw=true "HTML form for adding a user") 25 | 26 | ## Delete user 27 | ![Delete user form](screenshots/users-delete.png?raw=true "HTML form for deleting a user") 28 | 29 | ## Update user 30 | ![Update user form](screenshots/users-update.png?raw=true "HTML form for updating a user") 31 | 32 | # Logs 33 | 34 | ## Logs table 35 | ![Table of logs](screenshots/logs-table.png?raw=true "Logs presented in HTML table") 36 | 37 | # API 38 | 39 | ## API table 40 | ![Table of API tokens](screenshots/api-table.png?raw=true "API tokens presented in HTML table") 41 | 42 | ## Delete API token 43 | ![Delete API token form](screenshots/api-delete.png?raw=true "HTML form for deleting API token") 44 | 45 | ## Update API token 46 | ![Update API token form](screenshots/api-update.png?raw=true "HTML form for updating API token") 47 | 48 | ## JSON results of successful API call 49 | ![Successful API call](screenshots/api-call-success.png?raw=true "JSON results of successful API call") -------------------------------------------------------------------------------- /html/assets/font-awesome/4.7.0/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | .fa-icon() { 5 | display: inline-block; 6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | 14 | .fa-icon-rotate(@degrees, @rotation) { 15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})"; 16 | -webkit-transform: rotate(@degrees); 17 | -ms-transform: rotate(@degrees); 18 | transform: rotate(@degrees); 19 | } 20 | 21 | .fa-icon-flip(@horiz, @vert, @rotation) { 22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)"; 23 | -webkit-transform: scale(@horiz, @vert); 24 | -ms-transform: scale(@horiz, @vert); 25 | transform: scale(@horiz, @vert); 26 | } 27 | 28 | 29 | // Only display content to screen readers. A la Bootstrap 4. 30 | // 31 | // See: http://a11yproject.com/posts/how-to-hide-content/ 32 | 33 | .sr-only() { 34 | position: absolute; 35 | width: 1px; 36 | height: 1px; 37 | padding: 0; 38 | margin: -1px; 39 | overflow: hidden; 40 | clip: rect(0,0,0,0); 41 | border: 0; 42 | } 43 | 44 | // Use in conjunction with .sr-only to only display content when it's focused. 45 | // 46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 47 | // 48 | // Credit: HTML5 Boilerplate 49 | 50 | .sr-only-focusable() { 51 | &:active, 52 | &:focus { 53 | position: static; 54 | width: auto; 55 | height: auto; 56 | margin: 0; 57 | overflow: visible; 58 | clip: auto; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /includes/EXAMPLE.settings.local.inc.php: -------------------------------------------------------------------------------- 1 | 3 | 4 | 26 | 27 |
28 |

29 | 30 |
31 | -------------------------------------------------------------------------------- /includes/class.csrf.inc.php: -------------------------------------------------------------------------------- 1 | get('csrf_token')) { 12 | // Token doesn't exist, create one 13 | self::set_token(); 14 | } 15 | // Return the token 16 | return $session->get('csrf_token'); 17 | } 18 | 19 | // Used to check a submitted token with a token stored in the session 20 | public static function check_token($submitted_token) { 21 | // Check if a token was submitted 22 | if($submitted_token) { 23 | // Token was submitted 24 | // Bring in the session variable 25 | global $session; 26 | 27 | // Check if the submitted token matches the one in the database 28 | if($submitted_token == $session->get('csrf_token')) { 29 | // Token is the same 30 | return true; 31 | } else { 32 | // Token is not the same 33 | return false; 34 | } 35 | } else { 36 | // Token wasn't submitted 37 | return false; 38 | } 39 | } 40 | 41 | // Used to set a token in the session if one couldn't be found 42 | private static function set_token() { 43 | // Bring in the $session variable 44 | global $session; 45 | // Generate a random token of 64 length 46 | $token = self::generate_token(64); 47 | // Store it in the $_SESSION 48 | $session->set('csrf_token', $token); 49 | } 50 | 51 | // Used to generate a token 52 | private static function generate_token($token_length) { 53 | // Initialise a variable used to store the token 54 | $token = null; 55 | // Create a salt of accepted characters 56 | $salt = "abcdefghjkmnpqrstuvxyzABCDEFGHIJKLMNOPQRSTUVXYZ0123456789"; 57 | 58 | srand((double)microtime()*1000000); 59 | $i = 0; 60 | while ($i < $token_length) { 61 | $num = rand() % strlen($salt); 62 | $tmp = substr($salt, $num, 1); 63 | $token = $token . $tmp; 64 | $i++; 65 | } 66 | // Return the token 67 | return $token; 68 | } 69 | 70 | }; // Close class 71 | // EOF -------------------------------------------------------------------------------- /html/logs.php: -------------------------------------------------------------------------------- 1 | authenticated) { 10 | $user->logout('not_authenticated'); 11 | }; // Close if(!$user->authenticated) 12 | 13 | // setting $datatables_required to 1 will ensure it is included in the in layout.head.inc.php and so the