diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..bca9ecd --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @Lissy93 diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..4a6da86 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,135 @@ +# Contributor Covenant Code of Conduct + +> This is our code of conduct, based upon the [Contributor Covenant](https://www.contributor-covenant.org/). +> It outlines a set of core values and norms that are essential in a just and equitable software commons. +> You must abide by these if you wish to contribute to this project. +> For contributing guidelines - see [`CONTRIBUTING.md`](https://github.com/Lissy93/git-into-open-source/blob/main/.github/CONTRIBUTING.md) +> +> **TLDR; Don't be a d!ck** + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +alicia . +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..e69de29 diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..989d52b --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [lissy93, kynrai] diff --git a/.github/README.md b/.github/README.md new file mode 100644 index 0000000..052a1d8 --- /dev/null +++ b/.github/README.md @@ -0,0 +1,122 @@ +

Web Check API

+

+ + +
+
+ A light-weight Go API for discovering website data
+ Web Check - Gives you Xray Vision for any Website +

+ +> [!NOTE] +> This is a very early work in progress, and is not yet feature complete or production ready. +> Stay tuned! + +--- + +## Usage + +### Developing + +#### Getting Started + +You will need [git](https://git-scm.com/) and [go](https://go.dev/) installed. +Then clone the repo and download dependencies. + +``` +git clone git@github.com:xray-web/web-check-api.git +cd web-check-api +go mod download +``` + +#### Start Server + +``` +make run +``` + +#### Run Tests + +``` +make test +``` + + +### Deploying + +#### Option 1: From Source + +Follow the setup instructions above. Then build the binaries. +Then execute the output executable directly (e.g. `./bin/app`) + +``` +make build +``` + +#### Option 2: From Docker + +``` +docker run -p 8080:8080 lissy93/web-check-api +``` + +#### Option 3: Download Executable +From the releases tab, download the compiled binary for your system, and execute it. + +--- + +## License + +> _**[Web Check](https://github.com/Lissy93/web-check)** is licensed under [MIT](https://github.com/xray-web/web-check-api/blob/HEAD/LICENSE) ยฉ [Alicia Sykes](https://aliciasykes.com) 2024._
+> For information, see TLDR Legal > MIT + +
+Expand License + +``` +The MIT License (MIT) +Copyright (c) Alicia Sykes + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sub-license, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included install +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANT ABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` + +
+ + + +

+ ยฉ Alicia Sykes 2024
+ Licensed under MIT
+
+ Thanks for visiting :) +

+ + + + + diff --git a/.github/SECURITY.txt b/.github/SECURITY.txt new file mode 100644 index 0000000..e69de29 diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md new file mode 100644 index 0000000..c4c31b6 --- /dev/null +++ b/.github/SUPPORT.md @@ -0,0 +1,43 @@ +# Support + +First and foremost, thank you for using Web Check! +We're committed to providing a welcoming environment and ensuring all users can +utilize our work effectively. This document outlines the various avenues available +if you need help. + +## ๐Ÿ“– Documentation + +Before reaching out with your query, we recommend: + +1. Reviewing the [`README`](/.github/README.md) for an overview of the project. +2. Checking out our [`CONTRIBUTING`](/.github/CONTRIBUTING.md) guidelines if you're looking to submit changes. +3. Familiarizing yourself with our [`CODE_OF_CONDUCT`](/.github/CODE_OF_CONDUCT.md) to understand community behavior expectations. + +## ๐Ÿ› Bug Reports & Feature Requests + +If you've identified a bug or want to request a new feature: + +1. Search the [Issues](https://github.com/xray-web/web-check-api/issues) to see if it's already been reported. +2. If not, open a new issue! Please provide as much information as possible to help us understand and address the issue quickly. + +## ๐Ÿ’ฌ Discussion & Questions + +For general discussion, questions about the project, or if you're unsure where to start: + +1. Join our community chat (if applicable). +2. Start a discussion on the project's [Discussion tab](https://github.com/xray-web/web-check-api/discussions). + +## ๐Ÿš€ Get Involved! + +If you're excited about our project, there are many ways to get involved: + +1. Star the repository โ€“ it helps boost visibility and shows your support! +2. Check out "good first issues" or "help wanted" tags in the [Issues section](https://github.com/xray-web/web-check-api/issues) to get started with contributions. +3. Spread the word in your network and community. + +## ๐Ÿ“ง Contact + +If you have specific concerns or need to reach out directly, contact the core maintainers: + +- **Maintainers** - [Email](mailto:maintainers@web-check.xyz) + diff --git a/.github/web-check.png b/.github/web-check.png new file mode 100644 index 0000000..569f7af Binary files /dev/null and b/.github/web-check.png differ diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..d131f88 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,50 @@ +name: ๐Ÿš€ Deploy to Fly +on: + workflow_dispatch: + push: + branches: + - main +jobs: + deploy: + name: Deploy app + runs-on: ubuntu-latest + concurrency: deploy-group + permissions: + deployments: write + steps: + - name: Checkout ๐Ÿ›Ž๏ธ + uses: actions/checkout@v4 + + - name: Setup Fly ๐Ÿงฐ + uses: superfly/flyctl-actions/setup-flyctl@master + + - name: Create GitHub deployment ๐Ÿ™ + uses: chrnorm/deployment-action@v2 + id: deployment + with: + token: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }} + environment-url: http://api.web-check.xyz + environment: production + + - name: Deploy to Fly.io ๐Ÿ›ฉ๏ธ + run: flyctl deploy --remote-only + env: + FLY_API_TOKEN: ${{ secrets.FLY_TOKEN }} + + - name: Update deployment status (success) โœ… + if: success() + uses: chrnorm/deployment-status@v2 + with: + token: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }} + environment-url: ${{ steps.deployment.outputs.environment_url }} + deployment-id: ${{ steps.deployment.outputs.deployment_id }} + state: 'success' + + - name: Update deployment status (failure) โŒ + if: failure() + uses: chrnorm/deployment-status@v2 + with: + token: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }} + environment-url: ${{ steps.deployment.outputs.environment_url }} + deployment-id: ${{ steps.deployment.outputs.deployment_id }} + state: 'failure' diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..a9cc3aa --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,74 @@ +name: ๐Ÿณ Build + Publish Multi-Platform Image + +on: + workflow_dispatch: + push: + branches: ['main'] + tags: ['*'] + paths: + - '**.go' + +env: + DH_IMAGE: lissy93/web-check-api + GH_IMAGE: ${{ github.repository_owner }}/${{ github.event.repository.name }} + +jobs: + docker: + runs-on: ubuntu-latest + permissions: { contents: read, packages: write } + if: "!contains(github.event.head_commit.message, '[ci-skip]')" + + steps: + - name: ๐Ÿ›Ž๏ธ Checkout Repo + uses: actions/checkout@v2 + + - name: ๐Ÿ—‚๏ธ Make Docker Meta + id: meta + uses: docker/metadata-action@v3 + with: + images: | + ${{ env.DH_IMAGE }} + ghcr.io/${{ env.GH_IMAGE }} + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=ref,event=branch + type=ref,event=tag + labels: | + maintainer=Lissy93 + org.opencontainers.image.title=Web-Check-API + org.opencontainers.image.description=REST API for revealing public data for any website + org.opencontainers.image.documentation=https://web-check.xyz + org.opencontainers.image.authors=Alicia Sykes + org.opencontainers.image.licenses=MIT + + - name: ๐Ÿ”ง Set up QEMU + uses: docker/setup-qemu-action@v1 + + - name: ๐Ÿ”ง Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: ๐Ÿ”‘ Login to DockerHub + uses: docker/login-action@v1 + with: + username: lissy93 + password: ${{ secrets.DOCKER_HUB_TOKEN }} + + - name: ๐Ÿ”‘ Login to GitHub Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: ๐Ÿšฆ Check Registry Status + uses: crazy-max/ghaction-docker-status@v1 + + - name: โš’๏ธ Build and push + uses: docker/build-push-action@v2 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64,linux/arm64,linux/arm/v7 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..b761739 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,32 @@ +name: ๐Ÿ› ๏ธ Compile Release Assets + +on: + release: + types: [created] + +jobs: + releases-matrix: + name: Release Go Binary + runs-on: ubuntu-latest + strategy: + matrix: + goos: [linux, windows, darwin] + goarch: ['386', amd64, arm64] + exclude: + - goarch: '386' + goos: darwin + - goarch: arm64 + goos: windows + steps: + - name: Checkout code ๐Ÿ›Ž๏ธ + uses: actions/checkout@v3 + - name: Compile Go binaries ๐Ÿ—๏ธ + uses: wangyoucao577/go-release-action@v1.29 + with: + github_token: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }} + goos: ${{ matrix.goos }} + goarch: ${{ matrix.goarch }} + goversion: 1.22.4 + project_path: '.' + binary_name: web-check-api + md5sum: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..b45e2da --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,42 @@ +name: ๐Ÿงช Execute Tests + +on: + pull_request: + branches: + - main + - develop + push: + branches: + - main + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout code ๐Ÿ›Ž๏ธ + uses: actions/checkout@v2 + + - name: Set up Go ๐Ÿงฐ + uses: actions/setup-go@v3 + with: + go-version: 1.22.4 + + - name: Install dependencies โฌ + run: go mod tidy + + - name: Run tests ๐Ÿ› ๏ธ + run: make test + + - name: Report coverage ๐Ÿ“ˆ + run: go test -coverprofile=coverage.out ./... + + - name: Upload coverage to Codecov ๐Ÿ“ค + uses: codecov/codecov-action@v2 + with: + files: coverage.out + flags: unittests + name: codecov-umbrella + fail_ci_if_error: true + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.gitignore b/.gitignore index 4c49bd7..896765b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,54 @@ +# Config files and secrets .env +.env.local +.env.production +.env.development +.env.test + +# Build directories and files +/build/ +/bin/ +/dist/ + +# Dependencies +/vendor/ + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test outputs and coverage reports +*.out + +# Compiled object files +*.o +*.a +*.swp + +# Logs and temporary files +*.log +*.tmp + +# Go test binary and cache +*.test +/testdata/ +/*.test +*.cover +/.go + +# OS-specific files +.DS_Store +Thumbs.db + +# Editor and IDE specific files +.idea/ +*.iml +*.code-workspace + +# Ignore compiled application binaries +web-check-api-linux-* +web-check-api-windows-* +web-check-api-darwin-* diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index e70431a..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "files.insertFinalNewline": true -} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..24b5a07 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +# Stage 1: Build the application +# Copy over go.mod, install dependencies, copy source code, build the app +FROM golang:1.22.4-alpine AS builder +WORKDIR /app +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 GOOS=linux go build -o /app/bin/app main.go + +# Stage 2: Run the application +# Create non-root user, copy bin from build stage, set perms, +# expose port, start health check and then run the app +FROM alpine:3.20 +RUN addgroup -S appgroup && adduser -S appuser -G appgroup +COPY --from=builder /app/bin/app /usr/local/bin/app +RUN chmod +x /usr/local/bin/app +USER appuser +EXPOSE 8080 +HEALTHCHECK \ + --interval=30s \ + --timeout=10s \ + --start-period=5s \ + --retries=3 \ + CMD curl -f http://localhost:8080/health || exit 1 +CMD ["app"] diff --git a/Makefile b/Makefile index 841612f..858b421 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,43 @@ $(shell cp -n .env.example .env) include .env export +# Run the application run: @go run main.go .PHONY: run +# Test the application test: @go test ./... -.PHONY: test \ No newline at end of file +.PHONY: test + +# Build the application +build: + @go build -o bin/app main.go +.PHONY: build + +# Clean the build artifacts +clean: + @rm -rf bin/ +.PHONY: clean + +# Lint the codebase +lint: + @golangci-lint run +.PHONY: lint + +# Format the codebase +format: + @go fmt ./... +.PHONY: format + +# Install dependencies +deps: + @go mod tidy + @go mod vendor +.PHONY: deps + +# Ensure .env file is sourced +env: + @source .env +.PHONY: env diff --git a/README.md b/README.md deleted file mode 100644 index 0e3ce96..0000000 --- a/README.md +++ /dev/null @@ -1,18 +0,0 @@ - -# Web Check API - -> [!NOTE] -> This is a very early work in progress, and is not yet feature complete or production ready. -> Stay tuned! - -### Start Server - -``` -make run -``` - -### Run Tests - -``` -make test -``` diff --git a/fly.toml b/fly.toml new file mode 100644 index 0000000..de9976a --- /dev/null +++ b/fly.toml @@ -0,0 +1,30 @@ +app = 'web-check-api' +primary_region = 'lhr' + +[build] + +[deploy] + strategy = "bluegreen" + +[http_service] + internal_port = 8080 + force_https = true + auto_stop_machines = true + auto_start_machines = true + min_machines_running = 1 + processes = ['app'] + +[[vm]] + memory = '1gb' + cpu_kind = 'shared' + cpus = 1 + +[[http_service.checks]] + interval = "2s" + grace_period = "5s" + method = "GET" + path = "/health" + protocol = "http" + port = 8080 + timeout = "2s" + tls_skip_verify = false diff --git a/handlers/carbon_test.go b/handlers/carbon_test.go index af33d54..f205514 100644 --- a/handlers/carbon_test.go +++ b/handlers/carbon_test.go @@ -12,7 +12,7 @@ import ( ) func TestHandleCarbon(t *testing.T) { - t.Parallel() + // t.Parallel() httpmock.Activate() defer httpmock.DeactivateAndReset() diff --git a/handlers/health-check.go b/handlers/health-check.go new file mode 100644 index 0000000..3b1a7e1 --- /dev/null +++ b/handlers/health-check.go @@ -0,0 +1,14 @@ +package handlers + +import ( + "net/http" +) + +// HandleHealthCheck returns the status of the application +func HandleHealthCheck() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write([]byte(`{"status":"ok", "message":"We're alive!"}`)) + }) +} diff --git a/handlers/rank_test.go b/handlers/rank_test.go index c510a14..38f206c 100644 --- a/handlers/rank_test.go +++ b/handlers/rank_test.go @@ -12,7 +12,7 @@ import ( ) func TestHandleGetRank(t *testing.T) { - t.Parallel() + // t.Parallel() tests := []struct { name string urlParam string diff --git a/handlers/social_tags_test.go b/handlers/social_tags_test.go index 22ff609..377b10d 100644 --- a/handlers/social_tags_test.go +++ b/handlers/social_tags_test.go @@ -11,7 +11,7 @@ import ( ) func TestHandleGetSocialTags(t *testing.T) { - t.Parallel() + // t.Parallel() tests := []struct { name string urlParam string @@ -64,7 +64,7 @@ func TestHandleGetSocialTags(t *testing.T) { for _, tc := range tests { tc := tc t.Run(tc.name, func(t *testing.T) { - t.Parallel() + // t.Parallel() defer gock.Off() if tc.urlParam != "" { diff --git a/handlers/tls_test.go b/handlers/tls_test.go index ef5f0cd..f9bcc56 100644 --- a/handlers/tls_test.go +++ b/handlers/tls_test.go @@ -51,7 +51,7 @@ func TestHandleTLS(t *testing.T) { for _, tc := range tests { tc := tc t.Run(tc.name, func(t *testing.T) { - t.Parallel() + // t.Parallel() defer gock.Off() if tc.urlParam != "" { diff --git a/server/server.go b/server/server.go index ff34d01..f039353 100644 --- a/server/server.go +++ b/server/server.go @@ -56,6 +56,7 @@ func (s *Server) routes() { s.mux.Handle("/api/status", handlers.HandleStatus()) s.mux.Handle("/api/screenshot", handlers.HandleScreenshot()) s.mux.Handle("/api/tech-stack", handlers.HandleTechStack()) + s.mux.Handle("GET /health", handlers.HandleHealthCheck()) } func (s *Server) Run() error {