Compare commits

..

5 Commits

Author SHA1 Message Date
Thomas Miceli
92bac3bf8c v1.8.1 2024-11-02 02:00:48 +01:00
Thomas Miceli
73c2fb55bc Fix confirm() popup messages (#370) 2024-11-02 01:40:10 +01:00
Thomas Miceli
75162b3ef9 Hide passkey login when login form is disabled (#369) 2024-11-02 01:06:14 +01:00
Thomas Miceli
d537153785 Fix Markdown preview (#368) 2024-11-02 01:05:43 +01:00
Thomas Miceli
97b9fa1100 Fix typos 2024-11-01 00:00:09 +01:00
18 changed files with 50 additions and 34 deletions

View File

@@ -1,6 +1,16 @@
# Changelog
## [1.8.0](https://github.com/thomiceli/opengist/compare/v1.7.5...v1.8.0) - 2024-09-12
## [1.8.1](https://github.com/thomiceli/opengist/compare/v1.8.0...v1.8.1) - 2024-11-02
See here how to [update](/docs/update.md) Opengist.
### Changed
- Hide passkey login when login form is disabled (#369)
### Fixed
- Markdown preview (#368)
- confirm() popup messages (#370)
## [1.8.0](https://github.com/thomiceli/opengist/compare/v1.7.5...v1.8.0) - 2024-10-31
See here how to [update](https://opengist.io/docs/update) Opengist.
### 🔴 Deprecations

View File

@@ -13,7 +13,7 @@ It is similar to [GitHub Gist](https://gist.github.com/), but open-source and co
![License](https://img.shields.io/github/license/thomiceli/opengist?color=blue)
[![Go CI](https://github.com/thomiceli/opengist/actions/workflows/go.yml/badge.svg)](https://github.com/thomiceli/opengist/actions/workflows/go.yml)
[![Go Report Card](https://goreportcard.com/badge/github.com/thomiceli/opengist)](https://goreportcard.com/report/github.com/thomiceli/opengist)
[![Translate](https://tr.opengist.io/widget/_/svg-badge.svg)](https://tr.opengist.io/projects/_/opengist/)
## Features
@@ -37,7 +37,7 @@ It is similar to [GitHub Gist](https://gist.github.com/), but open-source and co
Docker [images](https://github.com/thomiceli/opengist/pkgs/container/opengist) are available for each release :
```shell
docker pull ghcr.io/thomiceli/opengist:1.7
docker pull ghcr.io/thomiceli/opengist:1.8
```
It can be used in a `docker-compose.yml` file :
@@ -49,7 +49,7 @@ It can be used in a `docker-compose.yml` file :
```yml
services:
opengist:
image: ghcr.io/thomiceli/opengist:1.7
image: ghcr.io/thomiceli/opengist:1.8
container_name: opengist
restart: unless-stopped
ports:
@@ -76,9 +76,9 @@ Download the archive for your system from the release page [here](https://github
```shell
# example for linux amd64
wget https://github.com/thomiceli/opengist/releases/download/v1.8.0/opengist1.8.0-linux-amd64.tar.gz
wget https://github.com/thomiceli/opengist/releases/download/v1.8.1/opengist1.8.1-linux-amd64.tar.gz
tar xzvf opengist1.8.0-linux-amd64.tar.gz
tar xzvf opengist1.8.1-linux-amd64.tar.gz
cd opengist
chmod +x opengist
./opengist # with or without `--config config.yml`

View File

@@ -28,11 +28,11 @@ namespace: opengist
resources:
- namespace.yaml
- https://github.com/thomiceli/opengist/deploy/?ref:v1.8.0
- https://github.com/thomiceli/opengist/deploy/?ref:v1.8.1
images:
- name: ghcr.io/thomiceli/opengist
newTag: 1.8.0
newTag: 1.8.1
patches:
# Add your ingress

View File

@@ -4,9 +4,9 @@ Download the archive for your system from the release page [here](https://github
```shell
# example for linux amd64
wget https://github.com/thomiceli/opengist/releases/download/v1.8.0/opengist1.8.0-linux-amd64.tar.gz
wget https://github.com/thomiceli/opengist/releases/download/v1.8.1/opengist1.8.1-linux-amd64.tar.gz
tar xzvf opengist1.8.0-linux-amd64.tar.gz
tar xzvf opengist1.8.1-linux-amd64.tar.gz
cd opengist
chmod +x opengist
./opengist # with or without `--config config.yml`

View File

@@ -10,7 +10,7 @@ Requirements:
git clone https://github.com/thomiceli/opengist
cd opengist
git checkout v1.8.0 # optional, to checkout the latest release
git checkout v1.8.1 # optional, to checkout the latest release
make
./opengist

View File

@@ -27,9 +27,9 @@ Stop the running instance; then like your first installation of Opengist, downlo
```shell
# example for linux amd64
wget https://github.com/thomiceli/opengist/releases/download/v1.8.0/opengist1.8.0-linux-amd64.tar.gz
wget https://github.com/thomiceli/opengist/releases/download/v1.8.1/opengist1.8.1-linux-amd64.tar.gz
tar xzvf opengist1.8.0-linux-amd64.tar.gz
tar xzvf opengist1.8.1-linux-amd64.tar.gz
cd opengist
chmod +x opengist
./opengist # with or without `--config config.yml`

View File

@@ -37,7 +37,7 @@ var CmdStart = cli.Command{
Initialize(ctx)
go web.NewServer(os.Getenv("OG_DEV") == "1", path.Join(config.GetHomeDir(), "sessions")).Start()
go web.NewServer(os.Getenv("OG_DEV") == "1", path.Join(config.GetHomeDir(), "sessions"), false).Start()
go ssh.Start()
<-stopCtx.Done()

View File

@@ -52,6 +52,7 @@ gist.edit.change-visibility: Make
gist.edit.delete: Delete
gist.edit.cancel: Cancel
gist.edit.save: Save
gist.delete.confirm: Are you sure you want to delete this gist ?
gist.list.joined: Joined
gist.list.all: All gists

View File

@@ -164,7 +164,7 @@ type Server struct {
dev bool
}
func NewServer(isDev bool, sessionsPath string) *Server {
func NewServer(isDev bool, sessionsPath string, ignoreCsrf bool) *Server {
dev = isDev
flashStore = sessions.NewCookieStore([]byte("opengist"))
encryptKey, _ := utils.GenerateSecretKey(filepath.Join(sessionsPath, "session-encrypt.key"))
@@ -245,15 +245,16 @@ func NewServer(isDev bool, sessionsPath string) *Server {
// Web based routes
g1 := e.Group("")
{
if !dev {
if !ignoreCsrf {
g1.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
TokenLookup: "form:_csrf,header:X-CSRF-Token",
CookiePath: "/",
CookieHTTPOnly: true,
CookieSameSite: http.SameSiteStrictMode,
}))
g1.Use(csrfInit)
}
g1.Use(csrfInit)
g1.GET("/", create, logged)
g1.POST("/", processCreate, logged)
g1.POST("/preview", preview, logged)

View File

@@ -33,7 +33,7 @@ type testServer struct {
func newTestServer() (*testServer, error) {
s := &testServer{
server: web.NewServer(true, path.Join(config.GetHomeDir(), "tmp", "sessions")),
server: web.NewServer(true, path.Join(config.GetHomeDir(), "tmp", "sessions"), true),
}
go s.start()

View File

@@ -73,10 +73,14 @@ document.addEventListener("DOMContentLoaded", () => {
} else {
const formData = new FormData();
formData.append('content', editor.state.doc.toString());
let csrf = document.querySelector<HTMLInputElement>('form#create input[name="_csrf"]').value
fetch(`${baseUrl}/preview`, {
method: 'POST',
credentials: 'same-origin',
body: formData
body: formData,
headers: {
'X-CSRF-Token': csrf
}
}).then(r => r.text()).then(r => {
let divpreview = dom.querySelector("div.preview") as HTMLElement;
divpreview!.innerHTML = r;

View File

@@ -75,9 +75,9 @@
{{ .locale.Tr "gist.header.edit" }}
</a>
</div>
<form id="delete" onsubmit="return confirm('Are you sure you want to delete this gist ?')" class="ml-2 flex items-center" method="post" action="{{ $.c.ExternalUrl }}/{{ .gist.User.Username }}/{{ .gist.Identifier }}/delete">
<form id="delete" class="ml-2 flex items-center" method="post" action="{{ $.c.ExternalUrl }}/{{ .gist.User.Username }}/{{ .gist.Identifier }}/delete">
{{ .csrfHtml }}
<button type="submit" class="relative inline-flex items-center space-x-2 rounded-md border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-800 px-2 py-1.5 text-xs font-medium text-rose-600 dark:text-rose-400 hover:bg-rose-500 hover:text-white dark:hover:bg-rose-600 hover:border-rose-600 dark:hover:border-rose-700 dark:hover:text-white focus:border-primary-500 focus:outline-none focus:ring-1 focus:ring-primary-500">
<button type="submit" onclick="return confirm('{{ .locale.Tr "gist.delete.confirm" }}')" class="relative inline-flex items-center space-x-2 rounded-md border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-800 px-2 py-1.5 text-xs font-medium text-rose-600 dark:text-rose-400 hover:bg-rose-500 hover:text-white dark:hover:bg-rose-600 hover:border-rose-600 dark:hover:border-rose-700 dark:hover:text-white focus:border-primary-500 focus:outline-none focus:ring-1 focus:ring-primary-500">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>

View File

@@ -28,9 +28,9 @@
<td class="whitespace-nowrap px-2 py-2 text-sm text-slate-700 dark:text-slate-300">{{ $gist.NbLikes }}</td>
<td class="whitespace-nowrap px-2 py-2 text-sm text-slate-700 dark:text-slate-300"><span class="moment-timestamp-date">{{ $gist.CreatedAt }}</span></td>
<td class="relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium sm:pr-0">
<form action="{{ $.c.ExternalUrl }}/admin-panel/gists/{{ $gist.ID }}/delete" method="POST" onsubmit="return confirm('{{ $.locale.Tr "admin.gists.delete_confirm" }}')">
<form action="{{ $.c.ExternalUrl }}/admin-panel/gists/{{ $gist.ID }}/delete" method="POST">
{{ $.csrfHtml }}
<button type="submit" class="text-rose-500 hover:text-rose-600">{{ $.locale.Tr "admin.delete" }}</button>
<button type="submit" onclick="return confirm('{{ $.locale.Tr "admin.gists.delete_confirm" }}')" class="text-rose-500 hover:text-rose-600">{{ $.locale.Tr "admin.delete" }}</button>
</form>
</td>
</tr>

View File

@@ -53,9 +53,9 @@
<td class="whitespace-nowrap py-2 px-2 text-sm">{{ $invitation.NbUsed }}/{{ $invitation.NbMax }}</td>
<td class="whitespace-nowrap px-2 py-2 text-sm"><span class="moment-timestamp-date">{{ $invitation.ExpiresAt }}</span></td>
<td class="relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium sm:pr-0">
<form action="{{ $.c.ExternalUrl }}/admin-panel/invitations/{{ $invitation.ID }}/delete" method="POST" onsubmit="return confirm('{{ $.locale.Tr "admin.users.delete_confirm" }}')">
<form action="{{ $.c.ExternalUrl }}/admin-panel/invitations/{{ $invitation.ID }}/delete" method="POST">
{{ $.csrfHtml }}
<button type="submit" class="text-rose-500 hover:text-rose-600">{{ $.locale.Tr "admin.delete" }}</button>
<button type="submit" onclick="return confirm('{{ $.locale.Tr "admin.users.delete_confirm" }}')" class="text-rose-500 hover:text-rose-600">{{ $.locale.Tr "admin.delete" }}</button>
</form>
</td>
</tr>

View File

@@ -20,9 +20,9 @@
<td class="whitespace-nowrap px-2 py-2 text-sm text-slate-700 dark:text-slate-300"><a href="{{ $.c.ExternalUrl }}/{{ $user.Username }}">{{ $user.Username }}</a></td>
<td class="whitespace-nowrap px-2 py-2 text-sm text-slate-700 dark:text-slate-300"><span class="moment-timestamp-date">{{ $user.CreatedAt }}</span></td>
<td class="relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium sm:pr-0">
<form action="{{ $.c.ExternalUrl }}/admin-panel/users/{{ $user.ID }}/delete" method="POST" onsubmit="return confirm('{{ $.locale.Tr "admin.users.delete_confirm" }}')">
<form action="{{ $.c.ExternalUrl }}/admin-panel/users/{{ $user.ID }}/delete" method="POST">
{{ $.csrfHtml }}
<button type="submit" class="text-rose-500 hover:text-rose-600">{{ $.locale.Tr "admin.delete" }}</button>
<button type="submit" class="text-rose-500 hover:text-rose-600" onclick="return confirm('{{ $.locale.Tr "admin.users.delete_confirm" }}')">{{ $.locale.Tr "admin.delete" }}</button>
</form>
</td>
</tr>

View File

@@ -87,7 +87,7 @@
</div>
</div>
</div>
{{ if .isLoginPage }}
{{ if and (.isLoginPage) (not .disableForm) }}
<div class="">
<div class="mt-8 sm:w-full sm:max-w-md">
<div class="bg-white dark:bg-gray-900 rounded-md border border-1 border-gray-200 dark:border-gray-700 py-8 px-4 shadow sm:rounded-lg sm:px-10 ">

View File

@@ -28,9 +28,9 @@
</div>
</div>
</form>
<form id="delete" onsubmit="return confirm('Are you sure you want to delete this gist ?')" class="ml-2 flex items-center" method="post" action="{{ $.c.ExternalUrl }}/{{ .gist.User.Username }}/{{ .gist.Identifier }}/delete">
<form id="delete" class="ml-2 flex items-center" method="post" action="{{ $.c.ExternalUrl }}/{{ .gist.User.Username }}/{{ .gist.Identifier }}/delete">
{{ .csrfHtml }}
<button type="submit" class="relative inline-flex items-center space-x-2 rounded-md border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-800 px-2 py-1.5 text-xs font-medium text-rose-600 dark:text-rose-400 hover:bg-rose-500 hover:text-white dark:hover:bg-rose-600 hover:border-rose-600 dark:hover:border-rose-700 dark:hover:text-white focus:border-primary-500 focus:outline-none focus:ring-1 focus:ring-primary-500">
<button type="submit" onclick="return confirm('{{ .locale.Tr "gist.delete.confirm" }}')" class="relative inline-flex items-center space-x-2 rounded-md border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-800 px-2 py-1.5 text-xs font-medium text-rose-600 dark:text-rose-400 hover:bg-rose-500 hover:text-white dark:hover:bg-rose-600 hover:border-rose-600 dark:hover:border-rose-700 dark:hover:text-white focus:border-primary-500 focus:outline-none focus:ring-1 focus:ring-primary-500">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>

View File

@@ -218,10 +218,10 @@
<p class="text-xs text-gray-500 line-clamp-2">{{ $.locale.Tr "auth.mfa.passkey-last-used" }} <span class="moment-timestamp">{{ .LastUsedAt }}</span></p>
{{ end }}
</div>
<form action="{{ $.c.ExternalUrl }}/settings/passkeys/{{.ID}}" method="post" class="inline-block" onsubmit="return confirm('{{ $.locale.Tr "auth.mfa.delete-passkey-confirm" }}');">
<form action="{{ $.c.ExternalUrl }}/settings/passkeys/{{.ID}}" method="post" class="inline-block">
<input type="hidden" name="_method" value="DELETE">
{{ $.csrfHtml }}
<button type="submit" class="align-middle items-center leading-2 ml-2 px-3 py-1 border border-transparent border-gray-200 dark:border-gray-700 text-xs font-medium rounded-md shadow-sm text-white dark:text-white bg-rose-600 hover:bg-rose-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-rose-500">{{ $.locale.Tr "auth.mfa.delete-passkey" }}</button>
<button type="submit" onclick="return confirm('{{ $.locale.Tr "auth.mfa.delete-passkey-confirm" }}');" class="align-middle items-center leading-2 ml-2 px-3 py-1 border border-transparent border-gray-200 dark:border-gray-700 text-xs font-medium rounded-md shadow-sm text-white dark:text-white bg-rose-600 hover:bg-rose-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-rose-500">{{ $.locale.Tr "auth.mfa.delete-passkey" }}</button>
</form>
</div>
</li>
@@ -280,11 +280,11 @@
<p class="text-xs text-gray-500 line-clamp-2">{{ $.locale.Tr "settings.ssh-key-last-used" }} <span class="moment-timestamp">{{ .LastUsedAt }}</span></p>
{{ end }}
</div>
<form action="{{ $.c.ExternalUrl }}/settings/ssh-keys/{{.ID}}" method="post" class="inline-block" onsubmit="return confirm('{{ $.locale.Tr "settings.delete-ssh-key-confirm" }}')">
<form action="{{ $.c.ExternalUrl }}/settings/ssh-keys/{{.ID}}" method="post" class="inline-block">
<input type="hidden" name="_method" value="DELETE">
{{ $.csrfHtml }}
<button type="submit" class="align-middle items-center leading-2 ml-2 px-3 py-1 border border-transparent border-gray-200 dark:border-gray-700 text-xs font-medium rounded-md shadow-sm text-white dark:text-white bg-rose-600 hover:bg-rose-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-rose-500">{{ $.locale.Tr "settings.delete-ssh-key" }}</button>
<button type="submit" onclick="return confirm('{{ $.locale.Tr "settings.delete-ssh-key-confirm" }}')" class="align-middle items-center leading-2 ml-2 px-3 py-1 border border-transparent border-gray-200 dark:border-gray-700 text-xs font-medium rounded-md shadow-sm text-white dark:text-white bg-rose-600 hover:bg-rose-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-rose-500">{{ $.locale.Tr "settings.delete-ssh-key" }}</button>
</form>
</div>
</li>