Skip to content

Commit

Permalink
feat(clipboard): allow user to change domain used when copying to cli…
Browse files Browse the repository at this point in the history
…pboard
  • Loading branch information
bemble committed Nov 3, 2022
1 parent 795f1b6 commit 15fe005
Show file tree
Hide file tree
Showing 18 changed files with 142 additions and 37 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/docker-images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:

jobs:
build:
name: Build container
name: Build image
runs-on: ubuntu-latest
steps:
- name: Checkout
Expand All @@ -35,13 +35,13 @@ jobs:
run: cd server && go test -v ./...

- name: Login to DockerHub
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
username: ${{ github.repository_owner }}
password: ${{ secrets.HUB_TOKEN }}

- name: Log in to ghcr.io
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
Expand Down Expand Up @@ -82,7 +82,7 @@ jobs:
npm ci install
CI=false GENERATE_SOURCEMAP=false npm run build:docker
- name: Build and push
- name: Build docker image and push
id: docker_build
uses: docker/build-push-action@v2
with:
Expand Down
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,13 @@ docker build . -t shortpaste

You can customize the behavior using environment variables:.

| Environment Variable | Default Value | Behaviour |
| -------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------ |
| `API_KEY` | `CHANGE-IT-ASAP` | API key used to communicate with the API. |
| `BASE_PATH` | `/` | App base path (use it if the app does not have run its dedicated domain name). |
| `DEBUG` | | Whether the app runs in debug mode or not (basically just more logs). |
| `PORT` | 8080 | Port on which app is running, **should not be changed**. |
| Environment Variable | Default Value | Behaviour |
| -------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `API_KEY` | `CHANGE-IT-ASAP` | API key used to communicate with the API. |
| `BASE_PATH` | `/` | App base path (use it if the app does not have run its dedicated domain name). |
| `DOMAIN` | | Override shortened URL domain in front, when copy to clipboard (default is the actual page domain). Example: `https://sho.rt` |
| `DEBUG` | | Whether the app runs in debug mode or not (basically just more logs). |
| `PORT` | 8080 | Port on which app is running, **should not be changed**. |

## Securing

Expand Down Expand Up @@ -137,8 +138,8 @@ Your web browser should open on `http://localhost:3000`. The app is configured t

## TODO

- [ ] optimize build
- [ ] allow user to set the public url for shortened content
- [x] optimize build time
- [x] allow user to set the public url for shortened content
- [x] move from sqlite3 to modernc.org/sqlite to compile without CGO (and use scratch, lighter image)
- [ ] display status with version
- [ ] allow user to change language
Expand Down
55 changes: 38 additions & 17 deletions front/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,48 @@
import { Route } from "react-router-dom";
import classes from './app.module.scss';
import {MemoryRouter as Router} from "react-router-dom";
import classes from "./app.module.scss";
import { MemoryRouter as Router } from "react-router-dom";
import { ThemeProvider, createTheme } from "@mui/material";
import { Content, MainMenu } from './components';
import { Files, Links, Texts } from './pages';
import { Content, MainMenu } from "./components";
import { Files, Links, Texts } from "./pages";
import AppContext from "./app_context";
import { useEffect, useState } from "react";
import { App as ShortApp } from "./common/data.types";
import { appRepository } from "./repositories";
import { config } from "./core";

const theme = createTheme({
spacing: 16,
spacing: 16,
});

function App() {
return <Router basename={process.env.PUBLIC_URL}>
<ThemeProvider theme={theme}>
<div className={classes.root}>
<MainMenu />
<Content>
<Route path="/" element={<Links />} />
<Route path="/texts" element={<Texts />} />
<Route path="/files" element={<Files />} />
</Content>
</div>
</ThemeProvider>
</Router>;
const [isLoading, setIsLoading] = useState(true);
const [appContextValue, setAppContextValue] = useState<ShortApp>();
useEffect(() => {
(async() => {
const app = await appRepository.get()
setAppContextValue(app);
config.domain = app.domain;
setIsLoading(false);
})();
}, []);

return (
<Router basename={process.env.PUBLIC_URL}>
<ThemeProvider theme={theme}>
<AppContext.Provider value={appContextValue}>
<div className={classes.root}>
{!isLoading ? <><MainMenu />
<Content>
<Route path="/" element={<Links />} />
<Route path="/texts" element={<Texts />} />
<Route path="/files" element={<Files />} />
</Content>
</> : null}
</div>
</AppContext.Provider>
</ThemeProvider>
</Router>
);
}

export default App;
6 changes: 6 additions & 0 deletions front/src/app_context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { createContext } from "react";
import { App as ShortApp } from "./common/data.types";

const LinksContext = createContext<ShortApp|undefined>(undefined);

export default LinksContext;
8 changes: 6 additions & 2 deletions front/src/common/api.types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
export type Status = {
status: "up";
export type Config = {
domain: string;
version: string;
};

export type Status = {
status: "up" | "down";
};

export type Link = {
id: string;
link: string;
Expand Down
4 changes: 4 additions & 0 deletions front/src/common/data.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import {
Link as ShortPasteLink,
File as ShortPasteFile,
Text as ShortPasteText,
Config as ShortPasteConfig,
Status as ShortPasteStatus,
} from "./api.types";

type ShortenedData = {
Expand All @@ -13,3 +15,5 @@ export type Link = ShortPasteLink & ShortenedData & {};
export type File = ShortPasteFile & ShortenedData & {};

export type Text = ShortPasteText & ShortenedData & {};

export type App = ShortPasteConfig & ShortPasteStatus;
5 changes: 5 additions & 0 deletions front/src/core/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Text as ShortPasteText,
File as ShortPasteFile,
Status,
Config,
} from "../common/api.types";
import config from "./config";

Expand Down Expand Up @@ -79,6 +80,10 @@ class Api {
public getStatus(): Promise<AxiosResponse<Status>> {
return this._axiosInstance.get<Status>("/status");
}

public getConfig(): Promise<AxiosResponse<Config>> {
return this._axiosInstance.get<Config>("/config");
}
}

export default new Api();
9 changes: 9 additions & 0 deletions front/src/core/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export default class Config {
static domain: string = "";

static get apiKey(): string {
return process.env.REACT_APP_API_KEY || "%shortpaste-api-key-placeholder%";
}
Expand All @@ -19,4 +21,11 @@ export default class Config {
}
return `${window.location.origin}${baseURL}`;
}

static get shortenURL(): string {
if (this.domain !== "") {
return this.domain;
}
return this.baseURL;
}
}
11 changes: 11 additions & 0 deletions front/src/repositories/app_repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { api, config } from "../core";
import { App as ShortApp } from "../common/data.types";

export default class AppRepository {
static async get(): Promise<ShortApp> {
const { data: apiStatus } = await api.getStatus();
const { data: apiConfig } = await api.getConfig();

return { ...apiStatus, ...apiConfig };
}
}
2 changes: 1 addition & 1 deletion front/src/repositories/files_repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ export default class FilesRepository {
}

static getShortURL(f: ShortPasteFile): string {
return `${config.baseURL}/f/${f.id}`;
return `${config.shortenURL}/f/${f.id}`;
}
}
1 change: 1 addition & 0 deletions front/src/repositories/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default as appRepository } from "./app_repository";
export { default as linksRepository } from "./links_repository";
export { default as textsRepository } from "./texts_repository";
export { default as filesRepository } from "./files_repository";
2 changes: 1 addition & 1 deletion front/src/repositories/links_repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ export default class LinksRepository {
}

static getShortURL(l: ShortPasteLink): string {
return `${config.baseURL}/l/${l.id}`;
return `${config.shortenURL}/l/${l.id}`;
}
}
2 changes: 1 addition & 1 deletion front/src/repositories/texts_repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ export default class TextsRepository {
}

static getShortURL(t: ShortPasteText): string {
return `${config.baseURL}/t/${t.id}`;
return `${config.shortenURL}/t/${t.id}`;
}
}
3 changes: 3 additions & 0 deletions server/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ func Router(r chi.Router) {
r.Use(middleware.SetHeader("Content-Type", "application/json"))
r.Use(CheckApiKey)

r.Get(`/config`, ConfigList)
r.Get(`/status`, StatusList)

r.Get(`/links`, LinksList)
r.Post(`/links`, LinkAdd)
r.Delete(`/links/{id}`, LinkDelete)
Expand Down
16 changes: 16 additions & 0 deletions server/api/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package api

import (
"encoding/json"
"net/http"
"shortpaste/core/config"
)

func ConfigList(w http.ResponseWriter, r *http.Request) {
var list = map[string]interface{}{
"domain": config.GetDomain(),
"version": config.AppVersion(),
}
body, _ := json.Marshal(list)
w.Write(body)
}
4 changes: 1 addition & 3 deletions server/api/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ package api
import (
"encoding/json"
"net/http"
"shortpaste/core/config"
)

func StatusList(w http.ResponseWriter, r *http.Request) {
var list = map[string]interface{}{
"status": "up",
"version": config.AppVersion(),
"status": "up",
}
body, _ := json.Marshal(list)
w.Write(body)
Expand Down
8 changes: 8 additions & 0 deletions server/core/config/domain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package config

import "os"

func GetDomain() string {
domain := os.Getenv("DOMAIN")
return domain
}
18 changes: 18 additions & 0 deletions server/core/config/domain_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package config

import (
"os"
"testing"
)

func TestGetDomain(t *testing.T) {
os.Setenv("DOMAIN", "")

domain := GetDomain()

expectedDomain := ""

if expectedDomain != domain {
t.Fatalf("Expected base path %s, but got %s", expectedDomain, domain)
}
}

0 comments on commit 15fe005

Please sign in to comment.