Compare commits
244 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 29a2e80984 | |||
| fa576bc78f | |||
| 3e22dce117 | |||
| 9adcf58ae5 | |||
| 5266b2c71f | |||
| 94dded3785 | |||
| ac8a7d0bc9 | |||
| 6fca8350f9 | |||
| 9acb5413f6 | |||
| 08a2fe4edb | |||
| 6abe8f296b | |||
| a53a67be4a | |||
| b72cac3511 | |||
| 698b7301b6 | |||
| c940d36fff | |||
| cd12028845 | |||
| 3225605ef3 | |||
| 31dde20a2b | |||
| aa36ebc947 | |||
| 92434fa943 | |||
| 0164354463 | |||
| bdc737ce0c | |||
| 733b3a7550 | |||
| 3339a691e1 | |||
| 2eef43e8bf | |||
| 336d8e6574 | |||
| dfbff27483 | |||
| 24ce34c8d7 | |||
| 7abb1f960c | |||
| ec7df11d73 | |||
| 64fa7e23fc | |||
| 93ad59466b | |||
| 4b7f45a15e | |||
| 83f21d0ddf | |||
| 2906a89442 | |||
| 50f55b4308 | |||
| a8028e7dd0 | |||
| 15abc84ab0 | |||
| 8a09211310 | |||
| 42fcd29200 | |||
| dc2e6c2b06 | |||
| 0cfc0a4bee | |||
| 64f83f9a5f | |||
| dc2b58f865 | |||
| 34ebc629c2 | |||
| d1b45a83b8 | |||
| 01a8701a8c | |||
| 67fe53e32a | |||
| 7f6b8cc43d | |||
| 5fe999eb02 | |||
| ea429d650e | |||
| 7fe7d56999 | |||
| 4f89dfee49 | |||
| 017534bc07 | |||
| 5540069cce | |||
| e9a4ff8e74 | |||
| 1ad56760ce | |||
| 5582949008 | |||
| 290baf1c8d | |||
| f878e0ad66 | |||
| 178e440951 | |||
| 321be4733d | |||
| cab4fa1687 | |||
| 4804e5b3ab | |||
| 885ab64c2e | |||
| 8624531f78 | |||
| db0c0e7908 | |||
| d77a47765e | |||
| 05c0819776 | |||
| 16f963fa3d | |||
| e032cf1fda | |||
| 10c26f38c4 | |||
| d6b8222371 | |||
| 2c5abaaea4 | |||
| c1a0653847 | |||
| 9226c8292d | |||
| 5fafa81dc1 | |||
| b30d1dce89 | |||
| 2dad27eed6 | |||
| f5ffda8053 | |||
| 5703b95de3 | |||
| d406dc43c2 | |||
| 2ce44bd4e6 | |||
| 15b96f304b | |||
| ed931ef0cd | |||
| bf4ee18123 | |||
| 70af10ae6c | |||
| 9892e5bf60 | |||
| b9a8d45c07 | |||
| 7794c2f44b | |||
| eedc14401a | |||
| 4e14d70427 | |||
| 2a71690aaf | |||
| e4da00ca82 | |||
| 4fd14e5859 | |||
| 441f1fbb64 | |||
| bf194d7794 | |||
| d06e3dd892 | |||
| 6b25b53462 | |||
| 6d79c9f3e2 | |||
| a36957dd77 | |||
| 2f3499e4b9 | |||
| 3536d08477 | |||
| ee3166cdc2 | |||
| 7a117a22c8 | |||
| 9a66f6a254 | |||
| 5e94726ec1 | |||
| 66c3559e1c | |||
| 413e44be2f | |||
| ebc35c4519 | |||
| cd963179fd | |||
| 796a0ebdaa | |||
| 474f24e40e | |||
| b3a0f86431 | |||
| 1a31231569 | |||
| f1d4087317 | |||
| f4069e00cd | |||
| 8650faf0d8 | |||
| 796ef741e8 | |||
| 36ae6f9430 | |||
| 1945b97b72 | |||
| 392e61688d | |||
| db82e06665 | |||
| ac5c6123bc | |||
| 8add47739e | |||
| eac8e0bdba | |||
| 2815e0d36e | |||
| 2e998b110f | |||
| f45c963428 | |||
| 2fec40d7df | |||
| 215beb9d8a | |||
| b0c61ee044 | |||
| 16fb2213b5 | |||
| a0d0645453 | |||
| 1ef336a08b | |||
| aa3aa78204 | |||
| db0a078c0b | |||
| 1cf1278b3b | |||
| 70648dedd3 | |||
| 9634dde0dd | |||
| 077caa29f8 | |||
| a87478d3ac | |||
| 44349db597 | |||
| c70ae19c28 | |||
| 55fdc86e02 | |||
| 0721ab8bbf | |||
| 00c8a1ee21 | |||
| 1fc71a4111 | |||
| 0c4768fd2a | |||
| f9647614ab | |||
| a05795420a | |||
| 42d86bf57b | |||
| 201b52baf8 | |||
| f510b9c2a9 | |||
| 75bd365ca1 | |||
| 153c30eda8 | |||
| be7e6ed847 | |||
| 115109f612 | |||
| 037a912e21 | |||
| 984db1ef44 | |||
| c8fe929e09 | |||
| 181dc5127f | |||
| 303fc39966 | |||
| 730c2a6821 | |||
| bc10761b49 | |||
| cf14a0222c | |||
| b18b3812df | |||
| bb095641c2 | |||
| b78e610ce3 | |||
| 884b6b0270 | |||
| 7a1ab1292c | |||
| 87bb741013 | |||
| 5fe2083688 | |||
| 2ee84c2675 | |||
| 39a5b6b426 | |||
| c6ce928567 | |||
| 950a23b0f4 | |||
| b4fac3e4ae | |||
| 548e483ef8 | |||
| bad6b862ca | |||
| 4e336e11ee | |||
| 8588e9ebf1 | |||
| 11524d0f7d | |||
| d0bfd8dfd2 | |||
| 312200bf44 | |||
| 04f4bb83e9 | |||
| 9b2dd6522f | |||
| a05fe9c1f7 | |||
| 395401e9db | |||
| dbdc1c7f3f | |||
| ace4a00e29 | |||
| c80aa2a289 | |||
| 25e2e7ecc6 | |||
| 02be4773de | |||
| c988d84271 | |||
| 9d5d1a9f9a | |||
| 3a7cef15bd | |||
| 44d3a425cb | |||
| 1854d7d668 | |||
| e5f4048e9e | |||
| 5e58f60845 | |||
| a7760b331b | |||
| a419a690d4 | |||
| 39b0dc136c | |||
| d0e7879c89 | |||
| acfb41f129 | |||
| 5381aa3fbd | |||
| e20a10a6a1 | |||
| 949141a8e7 | |||
| e1bf3b50f4 | |||
| cf5e3da3a5 | |||
| 1699c09758 | |||
| 918e7c8dae | |||
| 86afe6c4b1 | |||
| ff97b359ad | |||
| 81b66d0039 | |||
| 8fa690b635 | |||
| 8c1cd87831 | |||
| cde2bad297 | |||
| 80d36cd72b | |||
| a579353198 | |||
| 7360e15d4e | |||
| 9dc2fa61b8 | |||
| 80fd49a59e | |||
| d30fa9199c | |||
| 8028b39b43 | |||
| ff81e6d536 | |||
| 00fad35c2a | |||
| 3b68a6f1be | |||
| bc91aef47d | |||
| 3debe78574 | |||
| fc1b3b31b5 | |||
| 4afd598df7 | |||
| d1d3f893ac | |||
| 830d07f84f | |||
| 0e30b9aef7 | |||
| b937aedc30 | |||
| 55d05eeae3 | |||
| d95d3dc282 | |||
| ab06c26527 | |||
| 1ca770895a | |||
| a85fa14f9c | |||
| b058d84f2c | |||
| 5fb05d8b1c |
@@ -2468,6 +2468,87 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "leitwerk-ag",
|
||||
"name": "LEITWERK AG",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/24418301?v=4",
|
||||
"profile": "https://www.leitwerk.de/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "adamboutcher",
|
||||
"name": "Adam",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1911435?v=4",
|
||||
"profile": "http://www.aboutcher.co.uk",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "sneak-it",
|
||||
"name": "Ian",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/16104273?v=4",
|
||||
"profile": "https://snksrv.com",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "bestlong",
|
||||
"name": "Shao Yu-Lung (Allen)",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/4023909?v=4",
|
||||
"profile": "http://blog.bestlong.idv.tw/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Haxatron",
|
||||
"name": "Haxatron",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/76475453?v=4",
|
||||
"profile": "https://github.com/Haxatron",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "exula",
|
||||
"name": "Bradley Coudriet",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/3842948?v=4",
|
||||
"profile": "http://bjcpgd.cias.rit.edu",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "UniversalSuperBox",
|
||||
"name": "Dalton Durst",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/21966173?v=4",
|
||||
"profile": "https://daltondur.st",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "TenOfTens",
|
||||
"name": "TenOfTens",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/48162670?v=4",
|
||||
"profile": "https://github.com/TenOfTens",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "savornicesei",
|
||||
"name": "Simona Avornicesei",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/917232?v=4",
|
||||
"profile": "http://www.avornicesei.com",
|
||||
"contributions": [
|
||||
"test"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+3
-1
@@ -145,10 +145,12 @@ APP_LOG_MAX_FILES=10
|
||||
APP_LOCKED=false
|
||||
APP_CIPHER=AES-256-CBC
|
||||
APP_FORCE_TLS=false
|
||||
APP_ALLOW_INSECURE_HOSTS=false
|
||||
GOOGLE_MAPS_API=
|
||||
LDAP_MEM_LIM=500M
|
||||
LDAP_TIME_LIM=600
|
||||
IMPORT_TIME_LIMIT=600
|
||||
IMPORT_MEMORY_LIMIT=500M
|
||||
REPORT_TIME_LIMIT=12000
|
||||
|
||||
REQUIRE_SAML=false
|
||||
API_THROTTLE_PER_MINUTE=120
|
||||
@@ -0,0 +1,82 @@
|
||||
# Snipe-IT (Alpine) Docker image build for hub.docker.com
|
||||
name: Docker images (Alpine)
|
||||
|
||||
# Run this Build for all pushes to 'master' or develop branch, or tagged releases.
|
||||
# Also run for PRs to ensure PR doesn't break Docker build process
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
tags:
|
||||
- 'v**'
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
# Ensure this job never runs on forked repos. It's only executed for 'snipe/snipe-it'
|
||||
if: github.repository == 'snipe/snipe-it'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# Define tags to use for Docker images based on Git tags/branches (for docker/metadata-action)
|
||||
# For a new commit on default branch (master), use the literal tag 'latest' on Docker image.
|
||||
# For a new commit on other branches, use the branch name as the tag for Docker image.
|
||||
# For a new tag, copy that tag name as the tag for Docker image.
|
||||
IMAGE_TAGS: |
|
||||
type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }},suffix=-alpine
|
||||
type=ref,event=branch,enable=${{ !endsWith(github.ref, github.event.repository.default_branch) }},suffix=-alpine
|
||||
type=ref,event=tag,suffix=-alpine
|
||||
# Define default tag "flavor" for docker/metadata-action per
|
||||
# https://github.com/docker/metadata-action#flavor-input
|
||||
# We turn off 'latest' tag by default.
|
||||
TAGS_FLAVOR: |
|
||||
latest=false
|
||||
|
||||
steps:
|
||||
# https://github.com/actions/checkout
|
||||
- name: Checkout codebase
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# https://github.com/docker/setup-buildx-action
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
# https://github.com/docker/login-action
|
||||
- name: Login to DockerHub
|
||||
# Only login if not a PR, as PRs only trigger a Docker build and not a push
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
||||
|
||||
###############################################
|
||||
# Build/Push the 'snipe/snipe-it' image
|
||||
###############################################
|
||||
# https://github.com/docker/metadata-action
|
||||
# Get Metadata for docker_build step below
|
||||
- name: Sync metadata (tags, labels) from GitHub to Docker for 'snipe-it' image
|
||||
id: meta_build
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: snipe/snipe-it
|
||||
tags: ${{ env.IMAGE_TAGS }}
|
||||
flavor: ${{ env.TAGS_FLAVOR }}
|
||||
|
||||
# https://github.com/docker/build-push-action
|
||||
- name: Build and push 'snipe-it' image
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile.alpine
|
||||
platforms: linux/amd64
|
||||
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
|
||||
# but we ONLY do an image push to DockerHub if it's NOT a PR
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
# Use tags / labels provided by 'docker/metadata-action' above
|
||||
tags: ${{ steps.meta_build.outputs.tags }}
|
||||
labels: ${{ steps.meta_build.outputs.labels }}
|
||||
@@ -0,0 +1,82 @@
|
||||
# Snipe-IT Docker image build for hub.docker.com
|
||||
name: Docker images
|
||||
|
||||
# Run this Build for all pushes to 'master' or develop branch, or tagged releases.
|
||||
# Also run for PRs to ensure PR doesn't break Docker build process
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
tags:
|
||||
- 'v**'
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
# Ensure this job never runs on forked repos. It's only executed for 'snipe/snipe-it'
|
||||
if: github.repository == 'snipe/snipe-it'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# Define tags to use for Docker images based on Git tags/branches (for docker/metadata-action)
|
||||
# For a new commit on default branch (master), use the literal tag 'latest' on Docker image.
|
||||
# For a new commit on other branches, use the branch name as the tag for Docker image.
|
||||
# For a new tag, copy that tag name as the tag for Docker image.
|
||||
IMAGE_TAGS: |
|
||||
type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }}
|
||||
type=ref,event=branch,enable=${{ !endsWith(github.ref, github.event.repository.default_branch) }}
|
||||
type=ref,event=tag
|
||||
# Define default tag "flavor" for docker/metadata-action per
|
||||
# https://github.com/docker/metadata-action#flavor-input
|
||||
# We turn off 'latest' tag by default.
|
||||
TAGS_FLAVOR: |
|
||||
latest=false
|
||||
|
||||
steps:
|
||||
# https://github.com/actions/checkout
|
||||
- name: Checkout codebase
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# https://github.com/docker/setup-buildx-action
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
# https://github.com/docker/login-action
|
||||
- name: Login to DockerHub
|
||||
# Only login if not a PR, as PRs only trigger a Docker build and not a push
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
||||
|
||||
###############################################
|
||||
# Build/Push the 'snipe/snipe-it' image
|
||||
###############################################
|
||||
# https://github.com/docker/metadata-action
|
||||
# Get Metadata for docker_build step below
|
||||
- name: Sync metadata (tags, labels) from GitHub to Docker for 'snipe-it' image
|
||||
id: meta_build
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: snipe/snipe-it
|
||||
tags: ${{ env.IMAGE_TAGS }}
|
||||
flavor: ${{ env.TAGS_FLAVOR }}
|
||||
|
||||
# https://github.com/docker/build-push-action
|
||||
- name: Build and push 'snipe-it' image
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: linux/amd64
|
||||
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
|
||||
# but we ONLY do an image push to DockerHub if it's NOT a PR
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
# Use tags / labels provided by 'docker/metadata-action' above
|
||||
tags: ${{ steps.meta_build.outputs.tags }}
|
||||
labels: ${{ steps.meta_build.outputs.labels }}
|
||||
@@ -77,6 +77,8 @@ COPY . /var/www/html
|
||||
|
||||
RUN a2enmod rewrite
|
||||
|
||||
COPY docker/column-statistics.cnf /etc/mysql/conf.d/column-statistics.cnf
|
||||
|
||||
############ INITIAL APPLICATION SETUP #####################
|
||||
|
||||
WORKDIR /var/www/html
|
||||
|
||||
@@ -32,6 +32,8 @@ RUN apk add --no-cache \
|
||||
mysql-client \
|
||||
tini
|
||||
|
||||
COPY docker/column-statistics.cnf /etc/mysql/conf.d/column-statistics.cnf
|
||||
|
||||
# Where apache's PID lives
|
||||
RUN mkdir -p /run/apache2 && chown apache:apache /run/apache2
|
||||
|
||||
|
||||
@@ -98,5 +98,6 @@ VOLUME [ "/var/lib/snipeit" ]
|
||||
|
||||
COPY --chown=www-data:www-data docker/docker-secrets.env /var/www/html/.env
|
||||
COPY --chmod=655 docker/docker-entrypoint.sh /usr/local/bin/docker-snipeit-entrypoint
|
||||
COPY docker/column-statistics.cnf /etc/mysql/conf.d/column-statistics.cnf
|
||||
ENTRYPOINT [ "/usr/local/bin/docker-snipeit-entrypoint" ]
|
||||
CMD [ "/usr/local/bin/docker-php-entrypoint", "php-fpm" ]
|
||||
@@ -1,5 +1,5 @@
|
||||
 [](https://crowdin.com/project/snipe-it) [](https://hub.docker.com/r/snipe/snipe-it/) [](https://twitter.com/snipeitapp) [](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
|
||||
[](#contributors) [](https://discord.gg/yZFtShAcKk) [](https://huntr.dev)
|
||||
[](#contributors) [](https://discord.gg/yZFtShAcKk) [](https://huntr.dev)
|
||||
|
||||
## Snipe-IT - Open Source Asset Management System
|
||||
|
||||
@@ -129,7 +129,8 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
||||
| [<img src="https://avatars.githubusercontent.com/u/36065681?v=4" width="110px;"/><br /><sub>David Valin Alonso</sub>](https://github.com/deivishome)<br />[💻](https://github.com/snipe/snipe-it/commits?author=deivishome "Code") | [<img src="https://avatars.githubusercontent.com/u/8290389?v=4" width="110px;"/><br /><sub>andreaci</sub>](https://github.com/andreaci)<br />[💻](https://github.com/snipe/snipe-it/commits?author=andreaci "Code") | [<img src="https://avatars.githubusercontent.com/u/1828542?v=4" width="110px;"/><br /><sub>Jelle Sebreghts</sub>](http://www.jellesebreghts.be)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Jelle-S "Code") | [<img src="https://avatars.githubusercontent.com/u/11180862?v=4" width="110px;"/><br /><sub>Michael Pietsch</sub>](https://github.com/Skywalker-11)<br /> | [<img src="https://avatars.githubusercontent.com/u/22068886?v=4" width="110px;"/><br /><sub>Masudul Haque Shihab</sub>](https://github.com/sh1hab)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sh1hab "Code") | [<img src="https://avatars.githubusercontent.com/u/16099942?v=4" width="110px;"/><br /><sub>Supapong Areeprasertkul</sub>](http://www.freedomdive.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zybersup "Code") | [<img src="https://avatars.githubusercontent.com/u/207358?v=4" width="110px;"/><br /><sub>Peter Sarossy</sub>](https://github.com/psarossy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=psarossy "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/11823649?v=4" width="110px;"/><br /><sub>Renee Margaret McConahy</sub>](https://github.com/nepella)<br />[💻](https://github.com/snipe/snipe-it/commits?author=nepella "Code") | [<img src="https://avatars.githubusercontent.com/u/5553884?v=4" width="110px;"/><br /><sub>JohnnyPicnic</sub>](https://github.com/JohnnyPicnic)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JohnnyPicnic "Code") | [<img src="https://avatars.githubusercontent.com/u/8799594?v=4" width="110px;"/><br /><sub>markbrule</sub>](https://github.com/markbrule)<br />[💻](https://github.com/snipe/snipe-it/commits?author=markbrule "Code") | [<img src="https://avatars.githubusercontent.com/u/1962801?v=4" width="110px;"/><br /><sub>Mike Campbell</sub>](https://github.com/mikecmpbll)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mikecmpbll "Code") | [<img src="https://avatars.githubusercontent.com/u/11973217?v=4" width="110px;"/><br /><sub>tbrconnect</sub>](https://github.com/tbrconnect)<br />[💻](https://github.com/snipe/snipe-it/commits?author=tbrconnect "Code") | [<img src="https://avatars.githubusercontent.com/u/12447225?v=4" width="110px;"/><br /><sub>kcoyo</sub>](https://github.com/kcoyo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kcoyo "Code") | [<img src="https://avatars.githubusercontent.com/u/494017?v=4" width="110px;"/><br /><sub>Travis Miller</sub>](https://travismiller.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=travismiller "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/8735148?v=4" width="110px;"/><br /><sub>Petri Asikainen</sub>](https://github.com/PetriAsi)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PetriAsi "Code") | [<img src="https://avatars.githubusercontent.com/u/11424540?v=4" width="110px;"/><br /><sub>derdeagle</sub>](https://github.com/derdeagle)<br />[💻](https://github.com/snipe/snipe-it/commits?author=derdeagle "Code") | [<img src="https://avatars.githubusercontent.com/u/176950?v=4" width="110px;"/><br /><sub>Mike Frysinger</sub>](https://wh0rd.org/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vapier "Code") | [<img src="https://avatars.githubusercontent.com/u/22044358?v=4" width="110px;"/><br /><sub>ALPHA</sub>](https://github.com/AL4AL)<br />[💻](https://github.com/snipe/snipe-it/commits?author=AL4AL "Code") | [<img src="https://avatars.githubusercontent.com/u/1042587?v=4" width="110px;"/><br /><sub>FliegenKLATSCH</sub>](https://www.ifern.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FliegenKLATSCH "Code") | [<img src="https://avatars.githubusercontent.com/u/442138?v=4" width="110px;"/><br /><sub>Jeremy Price</sub>](https://github.com/jerm)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jerm "Code") | [<img src="https://avatars.githubusercontent.com/u/84392209?v=4" width="110px;"/><br /><sub>Toreg87</sub>](https://github.com/Toreg87)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Toreg87 "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/67638596?v=4" width="110px;"/><br /><sub>Matthew Nickson</sub>](https://github.com/Computroniks)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Computroniks "Code") | [<img src="https://avatars.githubusercontent.com/u/1646397?v=4" width="110px;"/><br /><sub>Jethro Nederhof</sub>](https://jethron.id.au)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jethron "Code") | [<img src="https://avatars.githubusercontent.com/u/23289826?v=4" width="110px;"/><br /><sub>Oskar Stenberg</sub>](https://github.com/01ste02)<br />[💻](https://github.com/snipe/snipe-it/commits?author=01ste02 "Code") | [<img src="https://avatars.githubusercontent.com/u/82208283?v=4" width="110px;"/><br /><sub>Robert-Azelis</sub>](https://github.com/Robert-Azelis)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Robert-Azelis "Code") | [<img src="https://avatars.githubusercontent.com/u/60648387?v=4" width="110px;"/><br /><sub>Alexander William Smith</sub>](https://github.com/alwism)<br />[💻](https://github.com/snipe/snipe-it/commits?author=alwism "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/67638596?v=4" width="110px;"/><br /><sub>Matthew Nickson</sub>](https://github.com/Computroniks)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Computroniks "Code") | [<img src="https://avatars.githubusercontent.com/u/1646397?v=4" width="110px;"/><br /><sub>Jethro Nederhof</sub>](https://jethron.id.au)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jethron "Code") | [<img src="https://avatars.githubusercontent.com/u/23289826?v=4" width="110px;"/><br /><sub>Oskar Stenberg</sub>](https://github.com/01ste02)<br />[💻](https://github.com/snipe/snipe-it/commits?author=01ste02 "Code") | [<img src="https://avatars.githubusercontent.com/u/82208283?v=4" width="110px;"/><br /><sub>Robert-Azelis</sub>](https://github.com/Robert-Azelis)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Robert-Azelis "Code") | [<img src="https://avatars.githubusercontent.com/u/60648387?v=4" width="110px;"/><br /><sub>Alexander William Smith</sub>](https://github.com/alwism)<br />[💻](https://github.com/snipe/snipe-it/commits?author=alwism "Code") | [<img src="https://avatars.githubusercontent.com/u/24418301?v=4" width="110px;"/><br /><sub>LEITWERK AG</sub>](https://www.leitwerk.de/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=leitwerk-ag "Code") | [<img src="https://avatars.githubusercontent.com/u/1911435?v=4" width="110px;"/><br /><sub>Adam</sub>](http://www.aboutcher.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=adamboutcher "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/16104273?v=4" width="110px;"/><br /><sub>Ian</sub>](https://snksrv.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sneak-it "Code") | [<img src="https://avatars.githubusercontent.com/u/4023909?v=4" width="110px;"/><br /><sub>Shao Yu-Lung (Allen)</sub>](http://blog.bestlong.idv.tw/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=bestlong "Code") | [<img src="https://avatars.githubusercontent.com/u/76475453?v=4" width="110px;"/><br /><sub>Haxatron</sub>](https://github.com/Haxatron)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Haxatron "Code") | [<img src="https://avatars.githubusercontent.com/u/3842948?v=4" width="110px;"/><br /><sub>Bradley Coudriet</sub>](http://bjcpgd.cias.rit.edu)<br />[💻](https://github.com/snipe/snipe-it/commits?author=exula "Code") | [<img src="https://avatars.githubusercontent.com/u/21966173?v=4" width="110px;"/><br /><sub>Dalton Durst</sub>](https://daltondur.st)<br />[💻](https://github.com/snipe/snipe-it/commits?author=UniversalSuperBox "Code") | [<img src="https://avatars.githubusercontent.com/u/48162670?v=4" width="110px;"/><br /><sub>TenOfTens</sub>](https://github.com/TenOfTens)<br />[💻](https://github.com/snipe/snipe-it/commits?author=TenOfTens "Code") | [<img src="https://avatars.githubusercontent.com/u/917232?v=4" width="110px;"/><br /><sub>Simona Avornicesei</sub>](http://www.avornicesei.com)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=savornicesei "Tests") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
||||
@@ -40,7 +40,7 @@ class FixDoubleEscape extends Command
|
||||
|
||||
$tables = [
|
||||
'\App\Models\Asset' => ['name'],
|
||||
'\App\Models\License' => ['name'],
|
||||
'\App\Models\License' => ['name', 'license_name'],
|
||||
'\App\Models\Consumable' => ['name'],
|
||||
'\App\Models\Accessory' => ['name'],
|
||||
'\App\Models\Component' => ['name'],
|
||||
@@ -53,7 +53,7 @@ class FixDoubleEscape extends Command
|
||||
'\App\Models\Group' => ['name'],
|
||||
'\App\Models\Department' => ['name'],
|
||||
'\App\Models\Location' => ['name'],
|
||||
'\App\Models\User' => ['first_name', 'last_name'],
|
||||
'\App\Models\User' => ['first_name', 'last_name', 'jobtitle'],
|
||||
];
|
||||
|
||||
$count = array();
|
||||
@@ -69,10 +69,14 @@ class FixDoubleEscape extends Command
|
||||
$count[$classname]['classname']++;
|
||||
$count[$classname][$field] = 0;
|
||||
|
||||
foreach($classname::where("$field",'LIKE','%&%')->get() as $row) {
|
||||
$this->info('Updating '.$field.' for '.$classname);
|
||||
$row->{$field} = html_entity_decode($row->{$field},ENT_QUOTES);
|
||||
$row->save();
|
||||
foreach($classname::where("$field",'LIKE','%;%')->get() as $row) {
|
||||
|
||||
$fixed = html_entity_decode($row->{$field});
|
||||
if ($row->save()) {
|
||||
$this->info('Updating '.$field.' for '.$classname.' to '.$row->{$field}.' to '.$fixed);
|
||||
} else {
|
||||
$this->error('Could NOT update '.$field.' for '.$classname.' to '.$row->{$field}.' to '.$fixed.': '.$row->getErrors());
|
||||
}
|
||||
$count[$classname][$field]++;
|
||||
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ class LdapSync extends Command
|
||||
$ldap_result_last_name = Setting::getSettings()->ldap_lname_field;
|
||||
$ldap_result_first_name = Setting::getSettings()->ldap_fname_field;
|
||||
|
||||
$ldap_result_active_flag = Setting::getSettings()->ldap_active_flag_field;
|
||||
$ldap_result_active_flag = Setting::getSettings()->ldap_active_flag;
|
||||
$ldap_result_emp_num = Setting::getSettings()->ldap_emp_num;
|
||||
$ldap_result_email = Setting::getSettings()->ldap_email;
|
||||
$ldap_result_phone = Setting::getSettings()->ldap_phone_field;
|
||||
@@ -170,7 +170,6 @@ class LdapSync extends Command
|
||||
$pass = bcrypt($tmp_pass);
|
||||
|
||||
for ($i = 0; $i < $results["count"]; $i++) {
|
||||
if (empty($ldap_result_active_flag) || $results[$i][$ldap_result_active_flag][0] == "TRUE") {
|
||||
|
||||
$item = array();
|
||||
$item["username"] = isset($results[$i][$ldap_result_username][0]) ? $results[$i][$ldap_result_username][0] : "";
|
||||
@@ -192,6 +191,7 @@ class LdapSync extends Command
|
||||
|
||||
|
||||
$user = User::where('username', $item["username"])->first();
|
||||
|
||||
if ($user) {
|
||||
// Updating an existing user.
|
||||
$item["createorupdate"] = 'updated';
|
||||
@@ -199,7 +199,7 @@ class LdapSync extends Command
|
||||
// Creating a new user.
|
||||
$user = new User;
|
||||
$user->password = $pass;
|
||||
$user->activated = 0;
|
||||
$user->activated = 1; // newly created users can log in by default, unless AD's UAC is in use, or an active flag is set (below)
|
||||
$item["createorupdate"] = 'created';
|
||||
}
|
||||
|
||||
@@ -213,8 +213,19 @@ class LdapSync extends Command
|
||||
$user->country = $item["country"];
|
||||
$user->department_id = $department->id;
|
||||
|
||||
// Sync activated state for Active Directory.
|
||||
if ( array_key_exists('useraccountcontrol', $results[$i]) ) {
|
||||
if ( !empty($ldap_result_active_flag)) { // IF we have an 'active' flag set....
|
||||
// ....then *most* things that are truthy will activate the user. Anything falsey will deactivate them.
|
||||
// (Specifically, we don't handle a value of '0.0' correctly)
|
||||
$raw_value = @$results[$i][$ldap_result_active_flag][0];
|
||||
$filter_var = filter_var($raw_value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
||||
$boolean_cast = (bool)$raw_value;
|
||||
|
||||
$user->activated = $filter_var ?? $boolean_cast; // if filter_var() was true or false, use that. If it's null, use the $boolean_cast
|
||||
|
||||
} elseif ( array_key_exists('useraccountcontrol', $results[$i]) ) {
|
||||
// ....otherwise, (ie if no 'active' LDAP flag is defined), IF the UAC setting exists,
|
||||
// ....then use the UAC setting on the account to determine can-log-in vs. cannot-log-in
|
||||
|
||||
/* The following is _probably_ the correct logic, but we can't use it because
|
||||
some users may have been dependent upon the previous behavior, and this
|
||||
could cause additional access to be available to users they don't want
|
||||
@@ -240,16 +251,14 @@ class LdapSync extends Command
|
||||
'262688', // 0x40220 NORMAL_ACCOUNT, PASSWD_NOTREQD, SMARTCARD_REQUIRED
|
||||
'328192', // 0x50200 NORMAL_ACCOUNT, SMARTCARD_REQUIRED, DONT_EXPIRE_PASSWORD
|
||||
'328224', // 0x50220 NORMAL_ACCOUNT, PASSWD_NOT_REQD, SMARTCARD_REQUIRED, DONT_EXPIRE_PASSWORD
|
||||
'4194816',// 0x400200 NORMAL_ACCOUNT, DONT_REQ_PREAUTH
|
||||
'4260352',// 0x410200 NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD, DONT_REQ_PREAUTH
|
||||
'1049088',// 0x100200 NORMAL_ACCOUNT, NOT_DELEGATED
|
||||
];
|
||||
$user->activated = ( in_array($results[$i]['useraccountcontrol'][0], $enabled_accounts) ) ? 1 : 0;
|
||||
}
|
||||
|
||||
// If we're not using AD, and there isn't an activated flag set, activate all users
|
||||
elseif (empty($ldap_result_active_flag)) {
|
||||
$user->activated = 1;
|
||||
}
|
||||
} /* implied 'else' here - leave the $user->activated flag alone. Newly-created accounts will be active.
|
||||
already-existing accounts will be however the administrator has set them */
|
||||
|
||||
if ($item['ldap_location_override'] == true) {
|
||||
$user->location_id = $item['location_id'];
|
||||
@@ -279,7 +288,6 @@ class LdapSync extends Command
|
||||
}
|
||||
|
||||
array_push($summary, $item);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use App\Helpers\Helper;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Log;
|
||||
use JsonException;
|
||||
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
@@ -26,6 +27,7 @@ class Handler extends ExceptionHandler
|
||||
\Illuminate\Validation\ValidationException::class,
|
||||
\Intervention\Image\Exception\NotSupportedException::class,
|
||||
\League\OAuth2\Server\Exception\OAuthServerException::class,
|
||||
JsonException::class
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -60,6 +62,12 @@ class Handler extends ExceptionHandler
|
||||
return redirect()->back()->with('error', trans('general.token_expired'));
|
||||
}
|
||||
|
||||
// Invalid JSON exception
|
||||
// TODO: don't understand why we have to do this when we have the invalidJson() method, below, but, well, whatever
|
||||
if ($e instanceof JsonException) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'invalid JSON'), 422);
|
||||
}
|
||||
|
||||
|
||||
// Handle Ajax requests that fail because the model doesn't exist
|
||||
if ($request->ajax() || $request->wantsJson()) {
|
||||
@@ -76,10 +84,12 @@ class Handler extends ExceptionHandler
|
||||
switch ($e->getStatusCode()) {
|
||||
case '404':
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $statusCode . ' endpoint not found'), 404);
|
||||
case '405':
|
||||
case '429':
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Too many requests'), 429);
|
||||
case '405':
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Method not allowed'), 405);
|
||||
default:
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $statusCode), 405);
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $statusCode), $statusCode);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -121,6 +131,6 @@ class Handler extends ExceptionHandler
|
||||
*/
|
||||
protected function invalidJson($request, ValidationException $exception)
|
||||
{
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $exception->errors(), 400));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $exception->errors(), 422));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,8 @@ class AccessoriesController extends Controller
|
||||
$accessory->qty = request('qty');
|
||||
$accessory->user_id = Auth::user()->id;
|
||||
$accessory->supplier_id = request('supplier_id');
|
||||
$accessory->notes = request('notes');
|
||||
|
||||
|
||||
$accessory = $request->handleImages($accessory);
|
||||
|
||||
@@ -140,6 +142,7 @@ class AccessoriesController extends Controller
|
||||
$accessory->purchase_cost = Helper::ParseCurrency(request('purchase_cost'));
|
||||
$accessory->qty = request('qty');
|
||||
$accessory->supplier_id = request('supplier_id');
|
||||
$accessory->notes = request('notes');
|
||||
|
||||
$accessory = $request->handleImages($accessory);
|
||||
|
||||
|
||||
@@ -39,7 +39,8 @@ class AccessoriesController extends Controller
|
||||
'notes',
|
||||
'created_at',
|
||||
'min_amt',
|
||||
'company_id'
|
||||
'company_id',
|
||||
'notes',
|
||||
];
|
||||
|
||||
|
||||
@@ -69,6 +70,10 @@ class AccessoriesController extends Controller
|
||||
$accessories->where('location_id','=',$request->input('location_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('notes')) {
|
||||
$accessories->where('notes','=',$request->input('notes'));
|
||||
}
|
||||
|
||||
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
|
||||
// case we override with the actual count, so we should return 0 items.
|
||||
$offset = (($accessories) && ($request->get('offset') > $accessories->count())) ? $accessories->count() : $request->get('offset', 0);
|
||||
|
||||
@@ -33,6 +33,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
$maintenances = AssetMaintenance::with('asset', 'asset.model','asset.location', 'supplier', 'asset.company', 'admin');
|
||||
|
||||
if ($request->filled('search')) {
|
||||
@@ -101,6 +102,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// create a new model instance
|
||||
$assetMaintenance = new AssetMaintenance();
|
||||
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
||||
@@ -153,6 +155,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function update(Request $request, $assetMaintenanceId = null)
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// Check if the asset maintenance exists
|
||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
||||
|
||||
@@ -216,6 +219,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function destroy($assetMaintenanceId)
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// Check if the asset maintenance exists
|
||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
||||
|
||||
@@ -241,6 +245,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function show($assetMaintenanceId)
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
||||
if (!Company::isCurrentUserHasAccess($assetMaintenance->asset)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot view a maintenance for that asset'));
|
||||
|
||||
@@ -234,6 +234,7 @@ class AssetModelsController extends Controller
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
|
||||
$this->authorize('view.selectlists');
|
||||
$assetmodels = AssetModel::select([
|
||||
'models.id',
|
||||
'models.name',
|
||||
|
||||
@@ -55,7 +55,7 @@ class AssetsController extends Controller
|
||||
{
|
||||
|
||||
\Log::debug(Route::currentRouteName());
|
||||
|
||||
$filter_non_deprecable_assets = false;
|
||||
|
||||
/**
|
||||
* This looks MAD janky (and it is), but the AssetsController@index does a LOT of heavy lifting throughout the
|
||||
@@ -69,6 +69,7 @@ class AssetsController extends Controller
|
||||
* which would have been far worse of a mess. *sad face* - snipe (Sept 1, 2021)
|
||||
*/
|
||||
if (Route::currentRouteName()=='api.depreciation-report.index') {
|
||||
$filter_non_deprecable_assets = true;
|
||||
$transformer = 'App\Http\Transformers\DepreciationReportTransformer';
|
||||
$this->authorize('reports.view');
|
||||
} else {
|
||||
@@ -115,13 +116,28 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
$assets = Company::scopeCompanyables(Asset::select('assets.*'),"company_id","assets")
|
||||
->with('location', 'assetstatus', 'assetlog', 'company', 'defaultLoc','assignedTo',
|
||||
'model.category', 'model.manufacturer', 'model.fieldset','supplier');
|
||||
->with('location', 'assetstatus', 'company', 'defaultLoc','assignedTo',
|
||||
'model.category', 'model.manufacturer', 'model.fieldset','supplier'); //it might be tempting to add 'assetlog' here, but don't. It blows up update-heavy users.
|
||||
|
||||
|
||||
if ($filter_non_deprecable_assets) {
|
||||
$non_deprecable_models = AssetModel::select('id')->whereNotNull('depreciation_id')->get();
|
||||
$assets->InModelList($non_deprecable_models->toArray());
|
||||
}
|
||||
|
||||
// These are used by the API to query against specific ID numbers.
|
||||
// They are also used by the individual searches on detail pages like
|
||||
// locations, etc.
|
||||
|
||||
|
||||
// Search custom fields by column name
|
||||
foreach ($all_custom_fields as $field) {
|
||||
if ($request->filled($field->db_column_name())) {
|
||||
$assets->where($field->db_column_name(), '=', $request->input($field->db_column_name()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($request->filled('status_id')) {
|
||||
$assets->where('assets.status_id', '=', $request->input('status_id'));
|
||||
}
|
||||
@@ -844,13 +860,18 @@ class AssetsController extends Controller
|
||||
$asset->status_id = $request->input('status_id');
|
||||
}
|
||||
|
||||
$checkin_at = null;
|
||||
if ($request->filled('checkin_at')) {
|
||||
$checkin_at = $request->input('checkin_at');
|
||||
}
|
||||
|
||||
if ($asset->save()) {
|
||||
event(new CheckoutableCheckedIn($asset, $target, Auth::user(), $request->input('note')));
|
||||
event(new CheckoutableCheckedIn($asset, $target, Auth::user(), $request->input('note'), $checkin_at));
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkin.success')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkin.error')));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkin.error')));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ class CategoriesController extends Controller
|
||||
*/
|
||||
public function selectlist(Request $request, $category_type = 'asset')
|
||||
{
|
||||
|
||||
$this->authorize('view.selectlists');
|
||||
$categories = Category::select([
|
||||
'id',
|
||||
'name',
|
||||
|
||||
@@ -159,7 +159,7 @@ class CompaniesController extends Controller
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
|
||||
$this->authorize('view.selectlists');
|
||||
$companies = Company::select([
|
||||
'companies.id',
|
||||
'companies.name',
|
||||
|
||||
@@ -40,6 +40,7 @@ class ComponentsController extends Controller
|
||||
'purchase_cost',
|
||||
'qty',
|
||||
'image',
|
||||
'notes',
|
||||
];
|
||||
|
||||
|
||||
@@ -62,6 +63,10 @@ class ComponentsController extends Controller
|
||||
$components->where('location_id','=',$request->input('location_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('notes')) {
|
||||
$components->where('notes','=',$request->input('notes'));
|
||||
}
|
||||
|
||||
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
|
||||
// case we override with the actual count, so we should return 0 items.
|
||||
$offset = (($components) && ($request->get('offset') > $components->count())) ? $components->count() : $request->get('offset', 0);
|
||||
|
||||
@@ -42,6 +42,7 @@ class ConsumablesController extends Controller
|
||||
'item_no',
|
||||
'qty',
|
||||
'image',
|
||||
'notes',
|
||||
];
|
||||
|
||||
|
||||
@@ -74,6 +75,10 @@ class ConsumablesController extends Controller
|
||||
$consumables->where('location_id','=',$request->input('location_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('notes')) {
|
||||
$consumables->where('notes','=',$request->input('notes'));
|
||||
}
|
||||
|
||||
|
||||
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
|
||||
// case we override with the actual count, so we should return 0 items.
|
||||
|
||||
@@ -168,6 +168,7 @@ class DepartmentsController extends Controller
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
|
||||
$this->authorize('view.selectlists');
|
||||
$departments = Department::select([
|
||||
'id',
|
||||
'name',
|
||||
|
||||
@@ -82,6 +82,10 @@ class LicensesController extends Controller
|
||||
$licenses = $licenses->TextSearch($request->input('search'));
|
||||
}
|
||||
|
||||
if ($request->input('deleted')=='true') {
|
||||
$licenses->onlyTrashed();
|
||||
}
|
||||
|
||||
|
||||
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
|
||||
// case we override with the actual count, so we should return 0 items.
|
||||
|
||||
@@ -223,6 +223,8 @@ class LocationsController extends Controller
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
|
||||
$this->authorize('view.selectlists');
|
||||
|
||||
$locations = Location::select([
|
||||
'locations.id',
|
||||
'locations.name',
|
||||
|
||||
@@ -155,6 +155,7 @@ class ManufacturersController extends Controller
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
|
||||
$this->authorize('view.selectlists');
|
||||
$manufacturers = Manufacturer::select([
|
||||
'id',
|
||||
'name',
|
||||
|
||||
@@ -31,8 +31,8 @@ class PredefinedKitsController extends Controller
|
||||
|
||||
$offset = $request->input('offset', 0);
|
||||
$limit = $request->input('limit', 50);
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'assets_count';
|
||||
$order = $request->input('order') === 'desc' ? 'desc' : 'asc';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'name';
|
||||
$kits->orderBy($sort, $order);
|
||||
|
||||
$total = $kits->count();
|
||||
|
||||
@@ -17,6 +17,7 @@ use GuzzleHttp\Client;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\Models\Ldap; // forward-port of v4 LDAP model for Sync
|
||||
use App\Http\Requests\SlackSettingsRequest;
|
||||
|
||||
|
||||
class SettingsController extends Controller
|
||||
@@ -165,31 +166,41 @@ class SettingsController extends Controller
|
||||
public function slacktest(Request $request)
|
||||
{
|
||||
|
||||
$slack = new Client([
|
||||
'base_url' => e($request->input('slack_endpoint')),
|
||||
'defaults' => [
|
||||
'exceptions' => false
|
||||
]
|
||||
$validator = Validator::make($request->all(), [
|
||||
'slack_endpoint' => 'url|required_with:slack_channel|starts_with:https://hooks.slack.com/|nullable',
|
||||
'slack_channel' => 'required_with:slack_endpoint|starts_with:#|nullable',
|
||||
]);
|
||||
|
||||
|
||||
$payload = json_encode(
|
||||
[
|
||||
'channel' => e($request->input('slack_channel')),
|
||||
'text' => trans('general.slack_test_msg'),
|
||||
'username' => e($request->input('slack_botname')),
|
||||
'icon_emoji' => ':heart:'
|
||||
]);
|
||||
|
||||
try {
|
||||
$slack->post($request->input('slack_endpoint'),['body' => $payload]);
|
||||
return response()->json(['message' => 'Success'], 200);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['message' => 'Oops! Please check the channel name and webhook endpoint URL. Slack responded with: '.$e->getMessage()], 400);
|
||||
if ($validator->fails()) {
|
||||
return response()->json(['message' => 'Validation failed', 'errors' => $validator->errors()], 422);
|
||||
}
|
||||
|
||||
return response()->json(['message' => 'Something went wrong :( '], 400);
|
||||
// If validation passes, continue to the curl request
|
||||
$slack = new Client([
|
||||
'base_url' => e($request->input('slack_endpoint')),
|
||||
'defaults' => [
|
||||
'exceptions' => false,
|
||||
],
|
||||
]);
|
||||
|
||||
$payload = json_encode(
|
||||
[
|
||||
'channel' => e($request->input('slack_channel')),
|
||||
'text' => trans('general.slack_test_msg'),
|
||||
'username' => e($request->input('slack_botname')),
|
||||
'icon_emoji' => ':heart:',
|
||||
]);
|
||||
|
||||
try {
|
||||
$slack->post($request->input('slack_endpoint'), ['body' => $payload]);
|
||||
return response()->json(['message' => 'Success'], 200);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['message' => 'Please check the channel name and webhook endpoint URL ('.$request->input('slack_endpoint').'). Slack responded with: '.$e->getMessage()], 400);
|
||||
}
|
||||
|
||||
//}
|
||||
return response()->json(['message' => 'Something went wrong :( '], 400);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -155,6 +155,8 @@ class SuppliersController extends Controller
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
|
||||
$this->authorize('view.selectlists');
|
||||
|
||||
$suppliers = Supplier::select([
|
||||
'id',
|
||||
'name',
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\SaveUserRequest;
|
||||
use App\Http\Transformers\AccessoriesTransformer;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Http\Transformers\ConsumablesTransformer;
|
||||
use App\Http\Transformers\LicensesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Http\Transformers\UsersTransformer;
|
||||
@@ -131,6 +132,26 @@ class UsersController extends Controller
|
||||
$users = $users->where('users.manager_id','=',$request->input('manager_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('ldap_import')) {
|
||||
$users = $users->where('ldap_import', '=', $request->input('ldap_import'));
|
||||
}
|
||||
|
||||
if ($request->filled('assets_count')) {
|
||||
$users->has('assets', '=', $request->input('assets_count'));
|
||||
}
|
||||
|
||||
if ($request->filled('consumables_count')) {
|
||||
$users->has('consumables', '=', $request->input('consumables_count'));
|
||||
}
|
||||
|
||||
if ($request->filled('licenses_count')) {
|
||||
$users->has('licenses', '=', $request->input('licenses_count'));
|
||||
}
|
||||
|
||||
if ($request->filled('accessories_count')) {
|
||||
$users->has('accessories', '=', $request->input('accessories_count'));
|
||||
}
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$users = $users->TextSearch($request->input('search'));
|
||||
}
|
||||
@@ -448,6 +469,24 @@ class UsersController extends Controller
|
||||
return (new AssetsTransformer)->transformAssets($assets, $assets->count(), $request);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return JSON containing a list of consumables assigned to a user.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @param $userId
|
||||
* @return string JSON
|
||||
*/
|
||||
public function consumables(Request $request, $id)
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
$this->authorize('view', Consumable::class);
|
||||
$user = User::findOrFail($id);
|
||||
$consumables = $user->consumables;
|
||||
return (new ConsumablesTransformer)->transformConsumables($consumables, $consumables->count(), $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return JSON containing a list of accessories assigned to a user.
|
||||
*
|
||||
|
||||
@@ -50,6 +50,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
return view('asset_maintenances/index');
|
||||
}
|
||||
|
||||
@@ -66,6 +67,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
$asset = null;
|
||||
|
||||
if ($asset = Asset::find(request('asset_id'))) {
|
||||
@@ -96,6 +98,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// create a new model instance
|
||||
$assetMaintenance = new AssetMaintenance();
|
||||
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
||||
@@ -148,6 +151,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function edit($assetMaintenanceId = null)
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// Check if the asset maintenance exists
|
||||
if (is_null($assetMaintenance = AssetMaintenance::find($assetMaintenanceId))) {
|
||||
// Redirect to the improvement management page
|
||||
@@ -200,6 +204,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function update(Request $request, $assetMaintenanceId = null)
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// Check if the asset maintenance exists
|
||||
if (is_null($assetMaintenance = AssetMaintenance::find($assetMaintenanceId))) {
|
||||
// Redirect to the asset maintenance management page
|
||||
@@ -266,6 +271,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function destroy($assetMaintenanceId)
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// Check if the asset maintenance exists
|
||||
if (is_null($assetMaintenance = AssetMaintenance::find($assetMaintenanceId))) {
|
||||
// Redirect to the asset maintenance management page
|
||||
@@ -294,6 +300,8 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function show($assetMaintenanceId)
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
|
||||
// Check if the asset maintenance exists
|
||||
if (is_null($assetMaintenance = AssetMaintenance::find($assetMaintenanceId))) {
|
||||
// Redirect to the asset maintenance management page
|
||||
|
||||
@@ -155,7 +155,6 @@ class AssetModelsController extends Controller
|
||||
$model->requestable = $request->input('requestable', '0');
|
||||
|
||||
|
||||
|
||||
$this->removeCustomFieldsDefaultValues($model);
|
||||
|
||||
if ($request->input('custom_fieldset')=='') {
|
||||
@@ -168,7 +167,6 @@ class AssetModelsController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($model->save()) {
|
||||
return redirect()->route("models.index")->with('success', trans('admin/models/message.update.success'));
|
||||
}
|
||||
@@ -269,6 +267,7 @@ class AssetModelsController extends Controller
|
||||
*/
|
||||
public function getClone($modelId = null)
|
||||
{
|
||||
$this->authorize('create', AssetModel::class);
|
||||
// Check if the model exists
|
||||
if (is_null($model_to_clone = AssetModel::find($modelId))) {
|
||||
return redirect()->route('models.index')->with('error', trans('admin/models/message.does_not_exist'));
|
||||
@@ -462,7 +461,9 @@ class AssetModelsController extends Controller
|
||||
private function assignCustomFieldsDefaultValues(AssetModel $model, array $defaultValues)
|
||||
{
|
||||
foreach ($defaultValues as $customFieldId => $defaultValue) {
|
||||
if ($defaultValue) {
|
||||
if(is_array($defaultValue)){
|
||||
$model->defaultValues()->attach($customFieldId, ['default_value' => implode(', ', $defaultValue)]);
|
||||
}elseif ($defaultValue) {
|
||||
$model->defaultValues()->attach($customFieldId, ['default_value' => $defaultValue]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
if (isset($target)) {
|
||||
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), $request->input('expected_checkin', null), 'Checked out on asset creation', e($request->get('name')), $location);
|
||||
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), $request->input('expected_checkin', null), 'Checked out on asset creation', $request->get('name'), $location);
|
||||
}
|
||||
|
||||
$success = true;
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Assets;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\CheckInOutRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -121,6 +122,24 @@ class BulkAssetsController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
$changed = [];
|
||||
$asset = Asset::where('id' ,$assetId)->get();
|
||||
|
||||
foreach ($this->update_array as $key => $value) {
|
||||
if ($this->update_array[$key] != $asset->toArray()[0][$key]) {
|
||||
$changed[$key]['old'] = $asset->toArray()[0][$key];
|
||||
$changed[$key]['new'] = $this->update_array[$key];
|
||||
}
|
||||
}
|
||||
|
||||
$logAction = new Actionlog();
|
||||
$logAction->item_type = Asset::class;
|
||||
$logAction->item_id = $assetId;
|
||||
$logAction->created_at = date("Y-m-d H:i:s");
|
||||
$logAction->user_id = Auth::id();
|
||||
$logAction->log_meta = json_encode($changed);
|
||||
$logAction->logaction('update');
|
||||
|
||||
DB::table('assets')
|
||||
->where('id', $assetId)
|
||||
->update($this->update_array);
|
||||
|
||||
@@ -87,6 +87,8 @@ class ForgotPasswordController extends Controller
|
||||
\Log::info('Password reset attempt: User '.$request->input('username').'failed with exception: '.$e );
|
||||
}
|
||||
|
||||
// Prevent timing attack to enumerate users.
|
||||
usleep(500000 + random_int(0, 1500000));
|
||||
|
||||
if ($response === \Password::RESET_LINK_SENT) {
|
||||
\Log::info('Password reset attempt: User '.$request->input('username').' WAS found, password reset sent');
|
||||
|
||||
@@ -75,6 +75,13 @@ class LoginController extends Controller
|
||||
return redirect()->intended('/');
|
||||
}
|
||||
|
||||
// If the environment is set to ALWAYS require SAML, go straight to the SAML route.
|
||||
// We don't need to check other settings, as this should override those.
|
||||
if (config('app.require_saml')) {
|
||||
return redirect()->route('saml.login');
|
||||
}
|
||||
|
||||
|
||||
if ($this->saml->isEnabled() && Setting::getSettings()->saml_forcelogin == "1" && !($request->has('nosaml') || $request->session()->has('error'))) {
|
||||
return redirect()->route('saml.login');
|
||||
}
|
||||
@@ -197,6 +204,12 @@ class LoginController extends Controller
|
||||
*/
|
||||
public function login(Request $request)
|
||||
{
|
||||
|
||||
//If the environment is set to ALWAYS require SAML, return access denied
|
||||
if (config('app.require_saml')) {
|
||||
return view('errors.403');
|
||||
}
|
||||
|
||||
if (Setting::getSettings()->login_common_disabled == "1") {
|
||||
return view('errors.403');
|
||||
}
|
||||
@@ -363,7 +376,7 @@ class LoginController extends Controller
|
||||
if (Google2FA::verifyKey($user->two_factor_secret, $secret)) {
|
||||
$user->two_factor_enrolled = 1;
|
||||
$user->save();
|
||||
$request->session()->put('2fa_authed', 'true');
|
||||
$request->session()->put('2fa_authed', $user->id);
|
||||
return redirect()->route('home')->with('success', 'You are logged in!');
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ class BulkAssetModelsController extends Controller
|
||||
|
||||
// If deleting....
|
||||
if ($request->input('bulk_actions')=='delete') {
|
||||
$this->authorize('delete', AssetModel::class);
|
||||
$valid_count = 0;
|
||||
foreach ($models as $model) {
|
||||
if ($model->assets_count == 0) {
|
||||
@@ -42,7 +43,7 @@ class BulkAssetModelsController extends Controller
|
||||
|
||||
// Otherwise display the bulk edit screen
|
||||
}
|
||||
|
||||
$this->authorize('update', AssetModel::class);
|
||||
$nochange = ['NC' => 'No Change'];
|
||||
return view('models/bulk-edit', compact('models'))
|
||||
->with('fieldset_list', $nochange + Helper::customFieldsetList())
|
||||
@@ -63,7 +64,8 @@ class BulkAssetModelsController extends Controller
|
||||
*/
|
||||
public function update(Request $request)
|
||||
{
|
||||
|
||||
$this->authorize('update', AssetModel::class);
|
||||
|
||||
$models_raw_array = $request->input('ids');
|
||||
$update_array = array();
|
||||
|
||||
@@ -103,6 +105,8 @@ class BulkAssetModelsController extends Controller
|
||||
*/
|
||||
public function destroy(Request $request)
|
||||
{
|
||||
$this->authorize('delete', AssetModel::class);
|
||||
|
||||
$models_raw_array = $request->input('ids');
|
||||
|
||||
if ((is_array($models_raw_array)) && (count($models_raw_array) > 0)) {
|
||||
|
||||
@@ -78,6 +78,7 @@ class ComponentsController extends Controller
|
||||
$component->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost', null));
|
||||
$component->qty = $request->input('qty');
|
||||
$component->user_id = Auth::id();
|
||||
$component->notes = $request->input('notes');
|
||||
|
||||
$component = $request->handleImages($component);
|
||||
|
||||
@@ -147,6 +148,7 @@ class ComponentsController extends Controller
|
||||
$component->purchase_date = $request->input('purchase_date');
|
||||
$component->purchase_cost = Helper::ParseCurrency(request('purchase_cost'));
|
||||
$component->qty = $request->input('qty');
|
||||
$component->notes = $request->input('notes');
|
||||
|
||||
$component = $request->handleImages($component);
|
||||
|
||||
|
||||
@@ -78,6 +78,8 @@ class ConsumablesController extends Controller
|
||||
$consumable->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost'));
|
||||
$consumable->qty = $request->input('qty');
|
||||
$consumable->user_id = Auth::id();
|
||||
$consumable->notes = $request->input('notes');
|
||||
|
||||
|
||||
|
||||
$consumable = $request->handleImages($consumable);
|
||||
@@ -143,6 +145,7 @@ class ConsumablesController extends Controller
|
||||
$consumable->purchase_date = $request->input('purchase_date');
|
||||
$consumable->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost'));
|
||||
$consumable->qty = Helper::ParseFloat($request->input('qty'));
|
||||
$consumable->notes = $request->input('notes');
|
||||
|
||||
$consumable = $request->handleImages($consumable);
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ class CustomFieldsController extends Controller
|
||||
$this->authorize('create', CustomField::class);
|
||||
|
||||
$field = new CustomField([
|
||||
"name" => $request->get("name"),
|
||||
"name" => trim($request->get("name")),
|
||||
"element" => $request->get("element"),
|
||||
"help_text" => $request->get("help_text"),
|
||||
"field_values" => $request->get("field_values"),
|
||||
@@ -133,12 +133,23 @@ class CustomFieldsController extends Controller
|
||||
|
||||
$this->authorize('update', $field);
|
||||
|
||||
if ($field->fieldset()->detach($fieldset_id)) {
|
||||
return redirect()->route('fieldsets.show', ['fieldset' => $fieldset_id])
|
||||
->with("success", trans('admin/custom_fields/message.field.delete.success'));
|
||||
// Check that the field exists - this is mostly related to the demo, where we
|
||||
// rewrite the data every x minutes, so it's possible someone might be disassociating
|
||||
// a field from a fieldset just as we're wiping the database
|
||||
if (($field) && ($fieldset_id)) {
|
||||
|
||||
if ($field->fieldset()->detach($fieldset_id)) {
|
||||
return redirect()->route('fieldsets.show', ['fieldset' => $fieldset_id])
|
||||
->with("success", trans('admin/custom_fields/message.field.delete.success'));
|
||||
} else {
|
||||
return redirect()->back()->withErrors(['message' => "Field is in use and cannot be deleted."]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return redirect()->back()->withErrors(['message' => "Field is in-use"]);
|
||||
return redirect()->back()->withErrors(['message' => "Error deleting field from fieldset"]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,20 +189,25 @@ class CustomFieldsController extends Controller
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$field = CustomField::find($id);
|
||||
if ($field = CustomField::find($id)) {
|
||||
|
||||
$this->authorize('update', $field);
|
||||
$this->authorize('update', $field);
|
||||
|
||||
$customFormat = '';
|
||||
if((stripos($field->format, 'regex') === 0) && ($field->format !== CustomField::PREDEFINED_FORMATS['MAC'])) {
|
||||
$customFormat = $field->format;
|
||||
}
|
||||
$customFormat = '';
|
||||
if((stripos($field->format, 'regex') === 0) && ($field->format !== CustomField::PREDEFINED_FORMATS['MAC'])) {
|
||||
$customFormat = $field->format;
|
||||
}
|
||||
|
||||
return view("custom_fields.fields.edit",[
|
||||
'field' => $field,
|
||||
'customFormat' => $customFormat,
|
||||
'predefinedFormats' => Helper::predefined_formats()
|
||||
]);
|
||||
return view("custom_fields.fields.edit",[
|
||||
'field' => $field,
|
||||
'customFormat' => $customFormat,
|
||||
'predefinedFormats' => Helper::predefined_formats()
|
||||
]);
|
||||
}
|
||||
|
||||
return redirect()->route("fields.index")
|
||||
->with("error", trans('admin/custom_fields/message.field.invalid'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -212,7 +228,7 @@ class CustomFieldsController extends Controller
|
||||
|
||||
$this->authorize('update', $field);
|
||||
|
||||
$field->name = e($request->get("name"));
|
||||
$field->name = trim(e($request->get("name")));
|
||||
$field->element = e($request->get("element"));
|
||||
$field->field_values = e($request->get("field_values"));
|
||||
$field->user_id = Auth::id();
|
||||
|
||||
@@ -23,6 +23,12 @@ use Redirect;
|
||||
class CustomFieldsetsController extends Controller
|
||||
{
|
||||
|
||||
public function index()
|
||||
{
|
||||
return redirect()->route("fields.index")
|
||||
->with("error", trans('admin/custom_fields/message.fieldset.does_not_exist'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates and stores a new custom field.
|
||||
*
|
||||
|
||||
@@ -6,15 +6,49 @@ use App\Helpers\Helper;
|
||||
|
||||
class ModalController extends Controller
|
||||
{
|
||||
function show($type, $itemId = null) {
|
||||
$view = view("modals.${type}");
|
||||
|
||||
if($type == "statuslabel") {
|
||||
$view->with('statuslabel_types', Helper::statusTypeList());
|
||||
/**
|
||||
* Load the modal views after confirming they are in the allowed_types array.
|
||||
* The allowed types away just prevents shithead skiddies from fuzzing the urls
|
||||
* with automated scripts and junking up the logs. - snipe
|
||||
*
|
||||
* @version v5.3.7-pre
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @author [A. Gianotto] [<snipe@snipe.net]
|
||||
* @return View
|
||||
*/
|
||||
function show ($type, $itemId = null) {
|
||||
|
||||
// These values should correspond to a file in resources/views/modals/
|
||||
$allowed_types = [
|
||||
'category',
|
||||
'kit-model',
|
||||
'kit-license',
|
||||
'kit-consumable',
|
||||
'kit-accessory',
|
||||
'location',
|
||||
'manufacturer',
|
||||
'model',
|
||||
'statuslabel',
|
||||
'supplier',
|
||||
'upload-file',
|
||||
'user',
|
||||
];
|
||||
|
||||
|
||||
if (in_array($type, $allowed_types)) {
|
||||
$view = view("modals.${type}");
|
||||
|
||||
if ($type == "statuslabel") {
|
||||
$view->with('statuslabel_types', Helper::statusTypeList());
|
||||
}
|
||||
if (in_array($type, ['kit-model', 'kit-license', 'kit-consumable', 'kit-accessory'])) {
|
||||
$view->with('kitId', $itemId);
|
||||
}
|
||||
return $view;
|
||||
}
|
||||
if(in_array($type, ['kit-model', 'kit-license', 'kit-consumable', 'kit-accessory'])) {
|
||||
$view->with('kitId', $itemId);
|
||||
}
|
||||
return $view;
|
||||
|
||||
abort(404,'Page not found');
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +113,12 @@ class ProfileController extends Controller
|
||||
* @return View
|
||||
*/
|
||||
public function api() {
|
||||
|
||||
// Make sure the self.api permission has been granted
|
||||
if (!Gate::allows('self.api')) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
return view('account/api');
|
||||
}
|
||||
|
||||
|
||||
@@ -515,6 +515,10 @@ class ReportsController extends Controller
|
||||
$header[] = trans('general.department');
|
||||
}
|
||||
|
||||
if ($request->filled('title')) {
|
||||
$header[] = trans('admin/users/table.title');
|
||||
}
|
||||
|
||||
if ($request->filled('status')) {
|
||||
$header[] = trans('general.status');
|
||||
}
|
||||
@@ -754,7 +758,6 @@ class ReportsController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($request->filled('department')) {
|
||||
if ($asset->checkedOutToUser()) {
|
||||
$row[] = (($asset->assignedto) && ($asset->assignedto->department)) ? $asset->assignedto->department->name : '';
|
||||
@@ -763,6 +766,14 @@ class ReportsController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->filled('title')) {
|
||||
if ($asset->checkedOutToUser()) {
|
||||
$row[] = ($asset->assignedto) ? $asset->assignedto->jobtitle : '';
|
||||
} else {
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->filled('status')) {
|
||||
$row[] = ($asset->assetstatus) ? $asset->assetstatus->name.' ('.$asset->present()->statusMeta.')' : '';
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Http\Requests\SettingsSamlRequest;
|
||||
use App\Http\Requests\SetupUserRequest;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Asset;
|
||||
use App\Models\User;
|
||||
use App\Notifications\FirstAdminNotification;
|
||||
use App\Notifications\MailTest;
|
||||
@@ -22,6 +23,7 @@ use Input;
|
||||
use Redirect;
|
||||
use Response;
|
||||
use App\Helpers\StorageHelper;
|
||||
use App\Http\Requests\SlackSettingsRequest;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Settings for
|
||||
@@ -620,6 +622,26 @@ class SettingsController extends Controller
|
||||
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
|
||||
}
|
||||
|
||||
// Check if the audit interval has changed - if it has, we want to update ALL of the assets audit dates
|
||||
if ($request->input('audit_interval') != $setting->audit_interval) {
|
||||
|
||||
// Be careful - this could be a negative number
|
||||
$audit_diff_months = ((int)$request->input('audit_interval') - (int)($setting->audit_interval));
|
||||
|
||||
// Grab all of the assets that have an existing next_audit_date
|
||||
$assets = Asset::whereNotNull('next_audit_date')->get();
|
||||
|
||||
// Update all of the assets' next_audit_date values
|
||||
foreach ($assets as $asset) {
|
||||
|
||||
if ($asset->next_audit_date != '') {
|
||||
$old_next_audit = new \DateTime($asset->next_audit_date);
|
||||
$asset->next_audit_date = $old_next_audit->modify($audit_diff_months.' month')->format('Y-m-d');
|
||||
$asset->forceSave();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$alert_email = rtrim($request->input('alert_email'), ',');
|
||||
$alert_email = trim($alert_email);
|
||||
$admin_cc_email = rtrim($request->input('admin_cc_email'), ',');
|
||||
@@ -667,25 +689,16 @@ class SettingsController extends Controller
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function postSlack(Request $request)
|
||||
public function postSlack(SlackSettingsRequest $request)
|
||||
{
|
||||
if (is_null($setting = Setting::getSettings())) {
|
||||
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
|
||||
}
|
||||
|
||||
$validatedData = $request->validate([
|
||||
'slack_channel' => 'regex:/(?<!\w)#\w+/|required_with:slack_endpoint|nullable',
|
||||
]);
|
||||
|
||||
|
||||
if ($validatedData) {
|
||||
|
||||
$setting->slack_endpoint = $request->input('slack_endpoint');
|
||||
$setting->slack_channel = $request->input('slack_channel');
|
||||
$setting->slack_botname = $request->input('slack_botname');
|
||||
|
||||
}
|
||||
|
||||
$setting->slack_endpoint = $request->input('slack_endpoint');
|
||||
$setting->slack_channel = $request->input('slack_channel');
|
||||
$setting->slack_botname = $request->input('slack_botname');
|
||||
|
||||
if ($setting->save()) {
|
||||
return redirect()->route('settings.index')
|
||||
->with('success', trans('admin/settings/message.update.success'));
|
||||
|
||||
@@ -184,6 +184,7 @@ class SuppliersController extends Controller
|
||||
*/
|
||||
public function show($supplierId = null)
|
||||
{
|
||||
$this->authorize('view', Supplier::class);
|
||||
$supplier = Supplier::find($supplierId);
|
||||
|
||||
if (isset($supplier->id)) {
|
||||
|
||||
@@ -34,7 +34,8 @@ class BulkUsersController extends Controller
|
||||
// Make sure there were users selected
|
||||
if (($request->filled('ids')) && (count($request->input('ids')) > 0)) {
|
||||
// Get the list of affected users
|
||||
$users = User::whereIn('id', array_keys(request('ids')))
|
||||
$user_raw_array = request('ids');
|
||||
$users = User::whereIn('id', $user_raw_array)
|
||||
->with('groups', 'assets', 'licenses', 'accessories')->get();
|
||||
|
||||
if ($request->input('bulk_actions') == 'edit') {
|
||||
|
||||
@@ -484,7 +484,6 @@ class UsersController extends Controller
|
||||
$user->first_name = '';
|
||||
$user->last_name = '';
|
||||
$user->email = substr($user->email, ($pos = strpos($user->email, '@')) !== false ? $pos : 0);
|
||||
|
||||
$user->id = null;
|
||||
|
||||
// Get this user groups
|
||||
|
||||
@@ -179,7 +179,7 @@ class ViewAssetsController extends Controller
|
||||
$logaction->logaction('request canceled');
|
||||
$settings->notify(new RequestAssetCancelation($data));
|
||||
return redirect()->route('requestable-assets')
|
||||
->with('success')->with('success', trans('admin/hardware/message.requests.cancel-success'));
|
||||
->with('success')->with('success', trans('admin/hardware/message.requests.cancel'));
|
||||
}
|
||||
|
||||
$logaction->logaction('requested');
|
||||
|
||||
+1
-2
@@ -24,6 +24,7 @@ class Kernel extends HttpKernel
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
\App\Http\Middleware\SecurityHeaders::class,
|
||||
\App\Http\Middleware\PreventBackHistory::class,
|
||||
\Fruitcake\Cors\HandleCors::class,
|
||||
|
||||
];
|
||||
|
||||
@@ -44,8 +45,6 @@ class Kernel extends HttpKernel
|
||||
],
|
||||
|
||||
'api' => [
|
||||
\Barryvdh\Cors\HandleCors::class,
|
||||
'throttle:120,1',
|
||||
'auth:api',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -32,7 +32,7 @@ class CheckForTwoFactor
|
||||
if ($settings = Setting::getSettings()) {
|
||||
if (Auth::check() && ($settings->two_factor_enabled != '')) {
|
||||
// This user is already 2fa-authed
|
||||
if ($request->session()->get('2fa_authed')) {
|
||||
if ($request->session()->get('2fa_authed')==Auth::user()->id) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,14 @@ abstract class Request extends FormRequest
|
||||
{
|
||||
protected $rules = [];
|
||||
|
||||
public function json($key = null, $default = null)
|
||||
{
|
||||
if ($this->ajax() || $this->wantsJson()) {
|
||||
json_decode($this->getContent(), false, 512, JSON_THROW_ON_ERROR); // ignore output, just throw
|
||||
}
|
||||
return parent::json($key, $default);
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
return $this->rules;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
class SlackSettingsRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'slack_endpoint' => 'url|required_with:slack_channel|starts_with:"https://hooks.slack.com"|nullable',
|
||||
'slack_channel' => 'required_with:slack_endpoint|starts_with:#|nullable',
|
||||
'slack_botname' => 'string|nullable',
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -82,7 +82,7 @@ class AccessoriesTransformer
|
||||
'first_name'=> e($user->first_name),
|
||||
'last_name'=> e($user->last_name),
|
||||
'employee_number' => e($user->employee_num),
|
||||
'checkout_notes' => $user->pivot->note,
|
||||
'checkout_notes' => e($user->pivot->note),
|
||||
'last_checkout' => Helper::getFormattedDateObject($user->pivot->created_at, 'datetime'),
|
||||
'type' => 'user',
|
||||
'available_actions' => ['checkin' => true]
|
||||
|
||||
@@ -19,6 +19,22 @@ class ActionlogsTransformer
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
private function clean_field($value)
|
||||
{
|
||||
// This object stuff is weird, and is used to make up for the fact that
|
||||
// older data can get strangely formatted if an asset existed,
|
||||
// then a new custom field is added, and the asset is saved again.
|
||||
// It can result in funnily-formatted strings like:
|
||||
//
|
||||
// {"_snipeit_right_sized_fault_tolerant_localareanetwo_1":
|
||||
// {"old":null,"new":{"value":"1579490695972","_snipeit_new_field_2":2,"_snipeit_new_field_3":"Monday, 20 January 2020 2:24:55 PM"}}
|
||||
// so we have to walk down that next level
|
||||
if(is_object($value) && isset($value->value)) {
|
||||
return $this->clean_field($value->value);
|
||||
}
|
||||
return is_scalar($value) || is_null($value) ? e($value) : e(json_encode($value));
|
||||
}
|
||||
|
||||
public function transformActionlog (Actionlog $actionlog, $settings = null)
|
||||
{
|
||||
$icon = $actionlog->present()->icon();
|
||||
@@ -31,45 +47,9 @@ class ActionlogsTransformer
|
||||
$meta_array = json_decode($actionlog->log_meta);
|
||||
|
||||
if ($meta_array) {
|
||||
foreach ($meta_array as $key => $value) {
|
||||
foreach ($value as $meta_key => $meta_value) {
|
||||
|
||||
if (is_array($meta_value)) {
|
||||
foreach ($meta_value as $meta_value_key => $meta_value_value) {
|
||||
$clean_meta[$key][$meta_value_key] = e($meta_value_value);
|
||||
}
|
||||
} else {
|
||||
|
||||
// This object stuff is weird, and is used to make up for the fact that
|
||||
// older data can get strangely formatted if an asset existed,
|
||||
// then a new custom field is added, and the asset is saved again.
|
||||
// It can result in funnily-formatted strings like:
|
||||
//
|
||||
// {"_snipeit_right_sized_fault_tolerant_localareanetwo_1":
|
||||
// {"old":null,"new":{"value":"1579490695972","_snipeit_new_field_2":2,"_snipeit_new_field_3":"Monday, 20 January 2020 2:24:55 PM"}}
|
||||
// so we have to walk down that next level
|
||||
|
||||
if (is_object($meta_value)) {
|
||||
|
||||
foreach ($meta_value as $meta_value_key => $meta_value_value) {
|
||||
|
||||
if ($meta_value_key == 'value') {
|
||||
$clean_meta[$key]['old'] = null;
|
||||
$clean_meta[$key]['new'] = e($meta_value->value);
|
||||
} else {
|
||||
$clean_meta[$meta_value_key]['old'] = null;
|
||||
$clean_meta[$meta_value_key]['new'] = e($meta_value_value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
$clean_meta[$key][$meta_key] = e($meta_value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
foreach ($meta_array as $fieldname => $fieldata) {
|
||||
$clean_meta[$fieldname]['old'] = $this->clean_field($fieldata->old);
|
||||
$clean_meta[$fieldname]['new'] = $this->clean_field($fieldata->new);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -118,6 +98,7 @@ class ActionlogsTransformer
|
||||
'action_date' => ($actionlog->action_date) ? Helper::getFormattedDateObject($actionlog->action_date, 'datetime'): Helper::getFormattedDateObject($actionlog->created_at, 'datetime'),
|
||||
|
||||
];
|
||||
//\Log::info("Clean Meta is: ".print_r($clean_meta,true));
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ class AssetsTransformer
|
||||
}
|
||||
return $asset->assigned ? [
|
||||
'id' => $asset->assigned->id,
|
||||
'name' => $asset->assigned->display_name,
|
||||
'name' => e($asset->assigned->display_name),
|
||||
'type' => $asset->assignedType()
|
||||
] : null;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ class ComponentsTransformer
|
||||
'id' => (int) $component->company->id,
|
||||
'name' => e($component->company->name)
|
||||
] : null,
|
||||
'notes' => ($component->notes) ? e($component->notes) : null,
|
||||
'created_at' => Helper::getFormattedDateObject($component->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($component->updated_at, 'datetime'),
|
||||
'user_can_checkout' => ($component->numRemaining() > 0) ? 1 : 0,
|
||||
|
||||
@@ -37,6 +37,7 @@ class ConsumablesTransformer
|
||||
'purchase_cost' => Helper::formatCurrencyOutput($consumable->purchase_cost),
|
||||
'purchase_date' => Helper::getFormattedDateObject($consumable->purchase_date, 'date'),
|
||||
'qty' => (int) $consumable->qty,
|
||||
'notes' => ($consumable->notes) ? e($consumable->notes) : null,
|
||||
'created_at' => Helper::getFormattedDateObject($consumable->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($consumable->updated_at, 'datetime'),
|
||||
];
|
||||
|
||||
@@ -9,13 +9,13 @@ use Illuminate\Database\Eloquent\Collection;
|
||||
class GroupsTransformer
|
||||
{
|
||||
|
||||
public function transformGroups (Collection $groups)
|
||||
public function transformGroups (Collection $groups, $total = null)
|
||||
{
|
||||
$array = array();
|
||||
foreach ($groups as $group) {
|
||||
$array[] = self::transformGroup($group);
|
||||
}
|
||||
return (new DatatablesTransformer)->transformDatatables($array);
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
public function transformGroup (Group $group)
|
||||
|
||||
@@ -45,7 +45,9 @@ class LicensesTransformer
|
||||
'category' => ($license->category) ? ['id' => (int) $license->category->id,'name'=> e($license->category->name)] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($license->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($license->updated_at, 'datetime'),
|
||||
'deleted_at' => Helper::getFormattedDateObject($license->deleted_at, 'datetime'),
|
||||
'user_can_checkout' => (bool) ($license->free_seats_count > 0),
|
||||
|
||||
];
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
|
||||
@@ -71,7 +71,7 @@ class AssetImporter extends ItemImporter
|
||||
$this->log("No Matching Asset, Creating a new one");
|
||||
$asset = new Asset;
|
||||
}
|
||||
|
||||
$this->item['notes'] = $this->findCsvMatch($row, 'asset_notes');
|
||||
$this->item['image'] = $this->findCsvMatch($row, "image");
|
||||
$this->item['requestable'] = $this->fetchHumanBoolean($this->findCsvMatch($row, "requestable"));;
|
||||
$asset->requestable = $this->fetchHumanBoolean($this->findCsvMatch($row, "requestable"));
|
||||
|
||||
@@ -177,7 +177,7 @@ class ItemImporter extends Importer
|
||||
*/
|
||||
public function createOrFetchAssetModel(array $row)
|
||||
{
|
||||
|
||||
$condition = array();
|
||||
$asset_model_name = $this->findCsvMatch($row, "asset_model");
|
||||
$asset_modelNumber = $this->findCsvMatch($row, "model_number");
|
||||
// TODO: At the moment, this means we can't update the model number if the model name stays the same.
|
||||
@@ -189,8 +189,16 @@ class ItemImporter extends Importer
|
||||
} elseif ((empty($asset_model_name)) && (empty($asset_modelNumber))) {
|
||||
$asset_model_name ='Unknown';
|
||||
}
|
||||
|
||||
if ((!empty($asset_model_name)) && (empty($asset_modelNumber))) {
|
||||
$condition[] = ['name', '=', $asset_model_name];
|
||||
} elseif ((!empty($asset_model_name)) && (!empty($asset_modelNumber))) {
|
||||
$condition[] = ['name', '=', $asset_model_name];
|
||||
$condition[] = ['model_number', '=', $asset_modelNumber];
|
||||
}
|
||||
|
||||
$editingModel = $this->updating;
|
||||
$asset_model = AssetModel::where(['name' => $asset_model_name, 'model_number' => $asset_modelNumber])->first();
|
||||
$asset_model = AssetModel::where($condition)->first();
|
||||
|
||||
if ($asset_model) {
|
||||
if (!$this->updating) {
|
||||
@@ -200,7 +208,12 @@ class ItemImporter extends Importer
|
||||
$this->log("Matching Model found, updating it.");
|
||||
$item = $this->sanitizeItemForStoring($asset_model, $editingModel);
|
||||
$item['name'] = $asset_model_name;
|
||||
$item['model_number'] = $asset_modelNumber;
|
||||
$item['notes'] = $this->findCsvMatch($row, 'model_notes');
|
||||
|
||||
if(!empty($asset_modelNumber)){
|
||||
$item['model_number'] = $asset_modelNumber;
|
||||
}
|
||||
|
||||
$asset_model->update($item);
|
||||
$asset_model->save();
|
||||
$this->log("Asset Model Updated");
|
||||
@@ -212,6 +225,7 @@ class ItemImporter extends Importer
|
||||
$item = $this->sanitizeItemForStoring($asset_model, $editingModel);
|
||||
$item['name'] = $asset_model_name;
|
||||
$item['model_number'] = $asset_modelNumber;
|
||||
$item['notes'] = $this->findCsvMatch($row, 'model_notes');
|
||||
|
||||
$asset_model->fill($item);
|
||||
$item = null;
|
||||
|
||||
@@ -32,7 +32,6 @@ class LicenseImporter extends ItemImporter
|
||||
{
|
||||
$editingLicense = false;
|
||||
$license = License::where('name', $this->item['name'])
|
||||
->where('serial', $this->item['serial'])
|
||||
->first();
|
||||
if ($license) {
|
||||
if (!$this->updating) {
|
||||
|
||||
@@ -52,6 +52,7 @@ class UserImporter extends ItemImporter
|
||||
$this->item['city'] = $this->findCsvMatch($row, 'city');
|
||||
$this->item['state'] = $this->findCsvMatch($row, 'state');
|
||||
$this->item['country'] = $this->findCsvMatch($row, 'country');
|
||||
$this->item['zip'] = $this->findCsvMatch($row, 'zip');
|
||||
$this->item['activated'] = ($this->fetchHumanBoolean($this->findCsvMatch($row, 'activated')) == 1) ? '1' : 0;
|
||||
$this->item['employee_num'] = $this->findCsvMatch($row, 'employee_num');
|
||||
$this->item['department_id'] = $this->createOrFetchDepartment($this->findCsvMatch($row, 'department'));
|
||||
|
||||
@@ -35,7 +35,7 @@ class Accessory extends SnipeModel
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $searchableAttributes = ['name', 'model_number', 'order_number', 'purchase_date'];
|
||||
protected $searchableAttributes = ['name', 'model_number', 'order_number', 'purchase_date', 'notes'];
|
||||
|
||||
/**
|
||||
* The relations and their attributes that should be included when searching the model.
|
||||
@@ -92,7 +92,8 @@ class Accessory extends SnipeModel
|
||||
'image',
|
||||
'qty',
|
||||
'min_amt',
|
||||
'requestable'
|
||||
'requestable',
|
||||
'notes',
|
||||
];
|
||||
|
||||
|
||||
|
||||
@@ -665,13 +665,15 @@ class Asset extends Depreciable
|
||||
*/
|
||||
public static function getExpiringWarrantee($days = 30)
|
||||
{
|
||||
$days = (is_null($days)) ? 30 : $days;
|
||||
|
||||
return Asset::where('archived', '=', '0')
|
||||
->whereNotNull('warranty_months')
|
||||
->whereNotNull('purchase_date')
|
||||
->whereNull('deleted_at')
|
||||
->whereRaw(\DB::raw('DATE_ADD(`purchase_date`,INTERVAL `warranty_months` MONTH) <= DATE(NOW() + INTERVAL '
|
||||
. $days
|
||||
. ' DAY) AND DATE_ADD(`purchase_date`,INTERVAL `warranty_months` MONTH) > NOW()'))
|
||||
. ' DAY) AND DATE_ADD(`purchase_date`, INTERVAL `warranty_months` MONTH) > NOW()'))
|
||||
->orderBy('purchase_date', 'ASC')
|
||||
->get();
|
||||
}
|
||||
@@ -814,7 +816,9 @@ class Asset extends Depreciable
|
||||
*/
|
||||
public function checkin_email()
|
||||
{
|
||||
return $this->model->category->checkin_email;
|
||||
if (($this->model) && ($this->model->category)) {
|
||||
return $this->model->category->checkin_email;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,6 +60,7 @@ class Component extends SnipeModel
|
||||
'order_number',
|
||||
'qty',
|
||||
'serial',
|
||||
'notes',
|
||||
];
|
||||
|
||||
use Searchable;
|
||||
@@ -69,7 +70,7 @@ class Component extends SnipeModel
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $searchableAttributes = ['name', 'order_number', 'serial', 'purchase_cost', 'purchase_date'];
|
||||
protected $searchableAttributes = ['name', 'order_number', 'serial', 'purchase_cost', 'purchase_date', 'notes'];
|
||||
|
||||
/**
|
||||
* The relations and their attributes that should be included when searching the model.
|
||||
|
||||
@@ -69,7 +69,8 @@ class Consumable extends SnipeModel
|
||||
'purchase_date',
|
||||
'qty',
|
||||
'min_amt',
|
||||
'requestable'
|
||||
'requestable',
|
||||
'notes',
|
||||
];
|
||||
|
||||
use Searchable;
|
||||
@@ -79,7 +80,7 @@ class Consumable extends SnipeModel
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $searchableAttributes = ['name', 'order_number', 'purchase_cost', 'purchase_date', 'item_no', 'model_number'];
|
||||
protected $searchableAttributes = ['name', 'order_number', 'purchase_cost', 'purchase_date', 'item_no', 'model_number', 'notes'];
|
||||
|
||||
/**
|
||||
* The relations and their attributes that should be included when searching the model.
|
||||
|
||||
@@ -627,6 +627,7 @@ class License extends Depreciable
|
||||
*/
|
||||
public static function getExpiringLicenses($days = 60)
|
||||
{
|
||||
$days = (is_null($days)) ? 60 : $days;
|
||||
|
||||
return License::whereNotNull('expiration_date')
|
||||
->whereNull('deleted_at')
|
||||
|
||||
@@ -115,6 +115,7 @@ trait Loggable
|
||||
|
||||
$log->location_id = null;
|
||||
$log->note = $note;
|
||||
$log->action_date = $action_date;
|
||||
|
||||
if (Auth::user()) {
|
||||
$log->user_id = Auth::user()->id;
|
||||
|
||||
@@ -52,10 +52,7 @@ class Setting extends Model
|
||||
'admin_cc_email' => 'email|nullable',
|
||||
'default_currency' => 'required',
|
||||
'locale' => 'required',
|
||||
'slack_endpoint' => 'url|required_with:slack_channel|nullable',
|
||||
'labels_per_page' => 'numeric',
|
||||
'slack_channel' => 'regex:/^[\#\@]?\w+/|required_with:slack_endpoint|nullable',
|
||||
'slack_botname' => 'string|nullable',
|
||||
'labels_width' => 'numeric',
|
||||
'labels_height' => 'numeric',
|
||||
'labels_pmargin_left' => 'numeric|nullable',
|
||||
|
||||
@@ -14,8 +14,8 @@ class Supplier extends SnipeModel
|
||||
|
||||
protected $rules = array(
|
||||
'name' => 'required|min:1|max:255|unique_undeleted',
|
||||
'address' => 'max:50|nullable',
|
||||
'address2' => 'max:50|nullable',
|
||||
'address' => 'max:250|nullable',
|
||||
'address2' => 'max:250|nullable',
|
||||
'city' => 'max:255|nullable',
|
||||
'state' => 'max:32|nullable',
|
||||
'country' => 'max:3|nullable',
|
||||
|
||||
@@ -109,7 +109,14 @@ class AccessoryPresenter extends Presenter
|
||||
"sortable" => true,
|
||||
"visible" => false,
|
||||
"title" => trans('general.order_number'),
|
||||
],[
|
||||
], [
|
||||
"field" => "notes",
|
||||
"searchable" => true,
|
||||
"sortable" => true,
|
||||
"visible" => false,
|
||||
"title" => trans('general.notes'),
|
||||
"formatter" => "notesFormatter"
|
||||
], [
|
||||
"field" => "change",
|
||||
"searchable" => false,
|
||||
"sortable" => false,
|
||||
|
||||
@@ -104,7 +104,14 @@ class ComponentPresenter extends Presenter
|
||||
"title" => trans('general.purchase_cost'),
|
||||
"visible" => true,
|
||||
"footerFormatter" => 'sumFormatter',
|
||||
],
|
||||
], [
|
||||
"field" => "notes",
|
||||
"searchable" => true,
|
||||
"sortable" => true,
|
||||
"visible" => false,
|
||||
"title" => trans('general.notes'),
|
||||
"formatter" => "notesFormatter"
|
||||
]
|
||||
];
|
||||
|
||||
$layout[] = [
|
||||
|
||||
@@ -118,13 +118,20 @@ class ConsumablePresenter extends Presenter
|
||||
"visible" => true,
|
||||
"footerFormatter" => 'sumFormatter',
|
||||
],[
|
||||
"field" => "notes",
|
||||
"searchable" => true,
|
||||
"sortable" => true,
|
||||
"visible" => false,
|
||||
"title" => trans('general.notes'),
|
||||
"formatter" => "notesFormatter"
|
||||
], [
|
||||
"field" => "change",
|
||||
"searchable" => false,
|
||||
"sortable" => false,
|
||||
"visible" => true,
|
||||
"title" => trans('general.change'),
|
||||
"formatter" => "consumablesInOutFormatter",
|
||||
], [
|
||||
], [
|
||||
"field" => "actions",
|
||||
"searchable" => false,
|
||||
"sortable" => false,
|
||||
|
||||
@@ -43,6 +43,17 @@ class AppServiceProvider extends ServiceProvider
|
||||
\Log::warning("'APP_FORCE_TLS' is set to true, but 'APP_URL' does not start with 'https://'. Will not force TLS on connections.");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - isn't it somehow 'gauche' to check the environment directly; shouldn't we be using config() somehow?
|
||||
if ( ! env('APP_ALLOW_INSECURE_HOSTS')) { // unless you set APP_ALLOW_INSECURE_HOSTS, you should PROHIBIT forging domain parts of URL via Host: headers
|
||||
$url_parts = parse_url(config('app.url'));
|
||||
if ($url_parts && array_key_exists('scheme', $url_parts) && array_key_exists('host', $url_parts)) { // check for the *required* parts of a bare-minimum URL
|
||||
\URL::forceRootUrl(config('app.url'));
|
||||
} else {
|
||||
\Log::error("Your APP_URL in your .env is misconfigured - it is: ".config('app.url').". Many things will work strangely unless you fix it.");
|
||||
}
|
||||
}
|
||||
|
||||
Schema::defaultStringLength(191);
|
||||
Asset::observe(AssetObserver::class);
|
||||
Accessory::observe(AccessoryObserver::class);
|
||||
|
||||
@@ -156,6 +156,8 @@ class AuthServiceProvider extends ServiceProvider
|
||||
return $user->hasAccess('self.checkout_assets');
|
||||
});
|
||||
|
||||
// This is largely used to determine whether to display the gear icon sidenav
|
||||
// in the left-side navigation
|
||||
Gate::define('backend.interact', function ($user) {
|
||||
return $user->can('view', Statuslabel::class)
|
||||
|| $user->can('view', AssetModel::class)
|
||||
@@ -168,7 +170,30 @@ class AuthServiceProvider extends ServiceProvider
|
||||
|| $user->can('view', Manufacturer::class)
|
||||
|| $user->can('view', CustomField::class)
|
||||
|| $user->can('view', CustomFieldset::class)
|
||||
|| $user->can('view', Depreciation::class);
|
||||
|| $user->can('view', Depreciation::class);
|
||||
});
|
||||
|
||||
|
||||
// This determines whether or not an API user should be able to get the selectlists.
|
||||
// This can seem a little confusing, since view properties may not have been granted
|
||||
// to the logged in API user, but creating assets, licenses, etc won't work
|
||||
// if the user can't view and interact with the select lists.
|
||||
Gate::define('view.selectlists', function ($user) {
|
||||
return $user->can('update', Asset::class)
|
||||
|| $user->can('create', Asset::class)
|
||||
|| $user->can('checkout', Asset::class)
|
||||
|| $user->can('checkin', Asset::class)
|
||||
|| $user->can('audit', Asset::class)
|
||||
|| $user->can('update', License::class)
|
||||
|| $user->can('create', License::class)
|
||||
|| $user->can('update', Component::class)
|
||||
|| $user->can('create', Component::class)
|
||||
|| $user->can('update', Consumable::class)
|
||||
|| $user->can('create', Consumable::class)
|
||||
|| $user->can('update', Accessory::class)
|
||||
|| $user->can('create', Accessory::class)
|
||||
|| $user->can('update', User::class)
|
||||
|| $user->can('create', User::class);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ class LdapAd extends LdapAdConfiguration
|
||||
'262688', // 0x40220 NORMAL_ACCOUNT, PASSWD_NOTREQD, SMARTCARD_REQUIRED
|
||||
'328192', // 0x50200 NORMAL_ACCOUNT, SMARTCARD_REQUIRED, DONT_EXPIRE_PASSWORD
|
||||
'328224', // 0x50220 NORMAL_ACCOUNT, PASSWD_NOT_REQD, SMARTCARD_REQUIRED, DONT_EXPIRE_PASSWORD
|
||||
'4194816',// 0x400200 NORMAL_ACCOUNT, DONT_REQ_PREAUTH
|
||||
'4260352',// 0x410200 NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD, DONT_REQ_PREAUTH
|
||||
'1049088',// 0x100200 NORMAL_ACCOUNT, NOT_DELEGATED
|
||||
'1114624',// 0x110200 NORMAL_ACCOUNT, NOT_DELEGATED, DONT_EXPIRE_PASSWORD
|
||||
|
||||
+1
-1
@@ -20,7 +20,6 @@
|
||||
"adldap2/adldap2": "^10.2",
|
||||
"alek13/slack": "^1.12",
|
||||
"bacon/bacon-qr-code": "^1.0",
|
||||
"barryvdh/laravel-cors": "^0.11.3",
|
||||
"barryvdh/laravel-debugbar": "^3.2",
|
||||
"doctrine/cache": "^1.10",
|
||||
"doctrine/common": "^2.12",
|
||||
@@ -31,6 +30,7 @@
|
||||
"enshrined/svg-sanitize": "^0.13.3",
|
||||
"erusev/parsedown": "^1.7",
|
||||
"fideloper/proxy": "^4.3",
|
||||
"fruitcake/laravel-cors": "^2.2",
|
||||
"guzzlehttp/guzzle": "^6.5",
|
||||
"intervention/image": "^2.5",
|
||||
"javiereguiluz/easyslugger": "^1.0",
|
||||
|
||||
Generated
+94
-81
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "252b4b452ca73e3e8f3d8543fce394d2",
|
||||
"content-hash": "6bd73d729675b968cf296bdf68f6a523",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adldap2/adldap2",
|
||||
@@ -139,36 +139,36 @@
|
||||
},
|
||||
{
|
||||
"name": "asm89/stack-cors",
|
||||
"version": "1.3.0",
|
||||
"version": "v2.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/asm89/stack-cors.git",
|
||||
"reference": "b9c31def6a83f84b4d4a40d35996d375755f0e08"
|
||||
"reference": "73e5b88775c64ccc0b84fb60836b30dc9d92ac4a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/asm89/stack-cors/zipball/b9c31def6a83f84b4d4a40d35996d375755f0e08",
|
||||
"reference": "b9c31def6a83f84b4d4a40d35996d375755f0e08",
|
||||
"url": "https://api.github.com/repos/asm89/stack-cors/zipball/73e5b88775c64ccc0b84fb60836b30dc9d92ac4a",
|
||||
"reference": "73e5b88775c64ccc0b84fb60836b30dc9d92ac4a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"symfony/http-foundation": "~2.7|~3.0|~4.0|~5.0",
|
||||
"symfony/http-kernel": "~2.7|~3.0|~4.0|~5.0"
|
||||
"php": "^7.2|^8.0",
|
||||
"symfony/http-foundation": "^4|^5|^6",
|
||||
"symfony/http-kernel": "^4|^5|^6"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.0 || ^4.8.10",
|
||||
"squizlabs/php_codesniffer": "^2.3"
|
||||
"phpunit/phpunit": "^7|^9",
|
||||
"squizlabs/php_codesniffer": "^3.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.2-dev"
|
||||
"dev-master": "2.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Asm89\\Stack\\": "src/Asm89/Stack/"
|
||||
"Asm89\\Stack\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@@ -189,9 +189,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/asm89/stack-cors/issues",
|
||||
"source": "https://github.com/asm89/stack-cors/tree/1.3.0"
|
||||
"source": "https://github.com/asm89/stack-cors/tree/v2.1.1"
|
||||
},
|
||||
"time": "2019-12-24T22:41:47+00:00"
|
||||
"time": "2022-01-18T09:12:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
@@ -333,72 +333,6 @@
|
||||
},
|
||||
"time": "2017-10-17T09:59:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "barryvdh/laravel-cors",
|
||||
"version": "v0.11.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fruitcake/laravel-cors.git",
|
||||
"reference": "03492f1a3bc74a05de23f93b94ac7cc5c173eec9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fruitcake/laravel-cors/zipball/03492f1a3bc74a05de23f93b94ac7cc5c173eec9",
|
||||
"reference": "03492f1a3bc74a05de23f93b94ac7cc5c173eec9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"asm89/stack-cors": "^1.2",
|
||||
"illuminate/support": "^5.5|^6",
|
||||
"php": ">=7",
|
||||
"symfony/http-foundation": "^3.1|^4",
|
||||
"symfony/http-kernel": "^3.1|^4"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/framework": "^5.5",
|
||||
"orchestra/testbench": "3.3.x|3.4.x|3.5.x|3.6.x|3.7.x",
|
||||
"phpunit/phpunit": "^4.8|^5.2|^7.0",
|
||||
"squizlabs/php_codesniffer": "^2.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.11-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Barryvdh\\Cors\\ServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Barryvdh\\Cors\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Barry vd. Heuvel",
|
||||
"email": "barryvdh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Laravel application",
|
||||
"keywords": [
|
||||
"api",
|
||||
"cors",
|
||||
"crossdomain",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/fruitcake/laravel-cors/issues",
|
||||
"source": "https://github.com/fruitcake/laravel-cors/tree/v0.11.4"
|
||||
},
|
||||
"time": "2019-08-28T11:27:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "barryvdh/laravel-debugbar",
|
||||
"version": "v3.6.2",
|
||||
@@ -2042,6 +1976,85 @@
|
||||
},
|
||||
"time": "2021-06-23T19:00:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fruitcake/laravel-cors",
|
||||
"version": "v2.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fruitcake/laravel-cors.git",
|
||||
"reference": "783a74f5e3431d7b9805be8afb60fd0a8f743534"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fruitcake/laravel-cors/zipball/783a74f5e3431d7b9805be8afb60fd0a8f743534",
|
||||
"reference": "783a74f5e3431d7b9805be8afb60fd0a8f743534",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"asm89/stack-cors": "^2.0.1",
|
||||
"illuminate/contracts": "^6|^7|^8|^9",
|
||||
"illuminate/support": "^6|^7|^8|^9",
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/framework": "^6|^7.24|^8",
|
||||
"orchestra/testbench-dusk": "^4|^5|^6|^7",
|
||||
"phpunit/phpunit": "^6|^7|^8|^9",
|
||||
"squizlabs/php_codesniffer": "^3.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.1-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Fruitcake\\Cors\\CorsServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Fruitcake\\Cors\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fruitcake",
|
||||
"homepage": "https://fruitcake.nl"
|
||||
},
|
||||
{
|
||||
"name": "Barry vd. Heuvel",
|
||||
"email": "barryvdh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Laravel application",
|
||||
"keywords": [
|
||||
"api",
|
||||
"cors",
|
||||
"crossdomain",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/fruitcake/laravel-cors/issues",
|
||||
"source": "https://github.com/fruitcake/laravel-cors/tree/v2.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://fruitcake.nl",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/barryvdh",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-02-23T14:25:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "6.5.5",
|
||||
@@ -11625,5 +11638,5 @@
|
||||
"platform-overrides": {
|
||||
"php": "7.2.5"
|
||||
},
|
||||
"plugin-api-version": "2.0.0"
|
||||
"plugin-api-version": "2.1.0"
|
||||
}
|
||||
|
||||
@@ -255,7 +255,20 @@ return [
|
||||
'enable_csp' => env('ENABLE_CSP', false),
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Require SAML Login
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Disable the ability to login via form login, and disables the 'nosaml'
|
||||
| workaround. It requires all logins to process via SAML login.
|
||||
| (This is for high security setups. If your SAML configuration is not
|
||||
| working, this option should be set to false. This option is not needed
|
||||
| to successfully configure SAML authentication.)
|
||||
|
|
||||
*/
|
||||
|
||||
'require_saml' => env('REQUIRE_SAML', false),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -412,4 +425,15 @@ return [
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| API Throttling
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This value determines the number of API requests permitted per minute
|
||||
|
|
||||
*/
|
||||
|
||||
'api_throttle_per_minute' => env('API_THROTTLE_PER_MINUTE', 120),
|
||||
|
||||
];
|
||||
|
||||
+8
-7
@@ -37,12 +37,13 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'supportsCredentials' => false,
|
||||
'allowedOrigins' => $allowed_origins,
|
||||
'allowedOriginsPatterns' => [],
|
||||
'allowedHeaders' => ['*'],
|
||||
'allowedMethods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
|
||||
'exposedHeaders' => [],
|
||||
'maxAge' => 0,
|
||||
'supports_credentials' => false,
|
||||
'allowed_origins' => $allowed_origins,
|
||||
'allowed_origins_patterns' => [],
|
||||
'allowed_headers' => ['*'],
|
||||
'allowed_methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
|
||||
'exposed_headers' => [],
|
||||
'max_age' => 0,
|
||||
'paths' => ['api/*', 'sanctum/csrf-cookie'],
|
||||
|
||||
];
|
||||
|
||||
+5
-5
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
return array (
|
||||
'app_version' => 'v5.3.2',
|
||||
'full_app_version' => 'v5.3.2 - build 6508-g7ce5993f5',
|
||||
'build_version' => '6508',
|
||||
'app_version' => 'vV5.4.1',
|
||||
'full_app_version' => 'vV5.4.1 - build 6746-g3e22dce11',
|
||||
'build_version' => '6746',
|
||||
'prerelease_version' => '',
|
||||
'hash_version' => 'g7ce5993f5',
|
||||
'full_hash' => 'v5.3.2-15-g7ce5993f5',
|
||||
'hash_version' => 'g3e22dce11',
|
||||
'full_hash' => 'V5.4.1-20-g3e22dce11',
|
||||
'branch' => 'master',
|
||||
);
|
||||
@@ -22,12 +22,12 @@ class UpdateGroupFieldForReporting extends Migration {
|
||||
|
||||
if (Schema::hasTable('permission_groups')) {
|
||||
|
||||
Group::where('id', 1)->update(['permissions' => '{"users-poop":1,"reports":1}']);
|
||||
Group::where('id', 2)->update(['permissions' => '{"users-pop":1,"reports":1}']);
|
||||
Group::where('id', 1)->update(['permissions' => '{"users-foo":1,"reports":1}']);
|
||||
Group::where('id', 2)->update(['permissions' => '{"users-foo":1,"reports":1}']);
|
||||
|
||||
} elseif (Schema::hasTable('groups')) {
|
||||
DB::update('update '.DB::getTablePrefix().'groups set permissions = ? where id = ?', ['{"admin-farts":1,"users":1,"reports":1}', 1]);
|
||||
DB::update('update '.DB::getTablePrefix().'groups set permissions = ? where id = ?', ['{"users-farts":1,"reports":1}', 2]);
|
||||
DB::update('update '.DB::getTablePrefix().'groups set permissions = ? where id = ?', ['{"admin-foo":1,"users":1,"reports":1}', 1]);
|
||||
DB::update('update '.DB::getTablePrefix().'groups set permissions = ? where id = ?', ['{"users-foo":1,"reports":1}', 2]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ class AddLdapFieldsToSettings extends Migration {
|
||||
$table->string('ldap_username_field')->nullable()->default('samaccountname');
|
||||
$table->string('ldap_lname_field')->nullable()->default('sn');
|
||||
$table->string('ldap_fname_field')->nullable()->default('givenname');
|
||||
$table->string('ldap_auth_filter_query')->nullable()->default('uid=samaccountname');
|
||||
$table->string('ldap_auth_filter_query')->nullable()->default('uid=');
|
||||
$table->integer('ldap_version')->nullable()->default(3);
|
||||
$table->string('ldap_active_flag')->nullable()->default(NULL);
|
||||
$table->string('ldap_emp_num')->nullable()->default(NULL);
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class ChangeSupplierAddressLength extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('suppliers', function (Blueprint $table) {
|
||||
//
|
||||
$table->string('address', 250)->nullable()->change();
|
||||
$table->string('address2', 250)->nullable()->change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('suppliers', function (Blueprint $table) {
|
||||
//
|
||||
$table->text('address', 50)->nullable()->default(null)->change();
|
||||
$table->text('address2', 50)->nullable()->default(null)->change();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use App\Models\Setting;
|
||||
|
||||
class BlankOutLdapActiveFlag extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
if ($s = Setting::getSettings()) {
|
||||
$s->ldap_active_flag = '';
|
||||
$s->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddNotesToAccessories extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('accessories', function (Blueprint $table) {
|
||||
$table->text("notes")->nullable()->default(null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('accessories', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('accessories', 'notes')) {
|
||||
$table->dropColumn('notes');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddNotesToComponents extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('components', function (Blueprint $table) {
|
||||
$table->text("notes")->nullable()->default(null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('components', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('components', 'notes')) {
|
||||
$table->dropColumn('notes');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddNotesToConsumables extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('consumables', function (Blueprint $table) {
|
||||
$table->text("notes")->nullable()->default(null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('consumables', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('consumables', 'notes')) {
|
||||
$table->dropColumn('notes');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
[mysqldump]
|
||||
column-statistics=0
|
||||
Generated
+7
-11
@@ -4233,7 +4233,7 @@
|
||||
"deep-equal": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
|
||||
"integrity": "sha1-tcmMlCzv+vfLBR4k4UNKJaLmB2o=",
|
||||
"integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-arguments": "^1.0.4",
|
||||
@@ -11630,8 +11630,7 @@
|
||||
"picomatch": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
|
||||
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
|
||||
"optional": true
|
||||
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg=="
|
||||
},
|
||||
"pify": {
|
||||
"version": "2.3.0",
|
||||
@@ -14237,7 +14236,6 @@
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
|
||||
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"is-extglob": "^2.1.1"
|
||||
}
|
||||
@@ -14251,8 +14249,7 @@
|
||||
"normalize-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"optional": true
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
|
||||
},
|
||||
"readdirp": {
|
||||
"version": "3.4.0",
|
||||
@@ -16241,9 +16238,9 @@
|
||||
"integrity": "sha1-G+i3twTdOFcVJwiu+x1KSzpp+zM="
|
||||
},
|
||||
"jquery-ui": {
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.13.0.tgz",
|
||||
"integrity": "sha512-Osf7ECXNTYHtKBkn9xzbIf9kifNrBhfywFEKxOeB/OVctVmLlouV9mfc2qXCp6uyO4Pn72PXKOnj09qXetopCw==",
|
||||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.13.1.tgz",
|
||||
"integrity": "sha512-2VlU59N5P4HaumDK1Z3XEVjSvegFbEOQRgpHUBaB2Ak98Axl3hFhJ6RFcNQNuk9SfL6WxIbuLst8dW/U56NSiA==",
|
||||
"requires": {
|
||||
"jquery": ">=1.8.0 <4.0.0"
|
||||
}
|
||||
@@ -18337,8 +18334,7 @@
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
|
||||
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"pify": {
|
||||
"version": "2.3.0",
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@
|
||||
"imagemin": "^5.3.1",
|
||||
"jquery-form-validator": "^2.3.79",
|
||||
"jquery-slimscroll": "^1.3.8",
|
||||
"jquery-ui": "^1.13.0",
|
||||
"jquery-ui": "^1.13.1",
|
||||
"jquery-ui-bundle": "^1.12.1",
|
||||
"jquery.iframe-transport": "^1.0.0",
|
||||
"less": "^3.13.1",
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
RewriteEngine On
|
||||
|
||||
# Needed for https://letsencrypt.org/ certificates.
|
||||
RewriteRule ^\.well-known/acme-challenge/ - [END]
|
||||
RewriteRule ^\.well-known/acme-challenge/ - [L]
|
||||
|
||||
# Uncomment these two lines to force SSL redirect in Apache
|
||||
# RewriteCond %{HTTPS} off
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -36,7 +36,7 @@
|
||||
*/
|
||||
|
||||
/*!
|
||||
* jQuery UI Widget 1.13.0
|
||||
* jQuery UI Widget 1.13.1
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user