Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/default expiry #161

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion History.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
* Only mention tool name in footer (#71)
* Replace redis client, move expiry into creation interface

With this release an old migration was removed and in case you are still using the `REDIS_EXPIRY` environment variable you need to switch to `SECRET_EXPIRY`. Also with the new redis client you might need to adjust the username in your `REDIS_URL` to a proper ACL username (or enable legacy auth in Redis) - see the README for the `REDIS_URL` format.
With this release an old migration was removed and in case you are still using the `REDIS_EXPIRY` environment variable you need to switch to `MAX_SECRET_EXPIRY`. Also with the new redis client you might need to adjust the username in your `REDIS_URL` to a proper ACL username (or enable legacy auth in Redis) - see the README for the `REDIS_URL` format.

# 1.0.0 / 2023-04-14

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ For a better setup you can choose the backend which is used to store the secrets
(pre Redis v6 use `auth` as user, afterwards use a user available in your ACLs)
- `REDIS_KEY` - Key prefix to store the keys under (Default `io.luzifer.ots`)
- Common options
- `SECRET_EXPIRY` - Expiry of the keys in seconds (Default `0` = no expiry)
- `MAX_SECRET_EXPIRY` - Expiry of the keys in seconds (Default `0` = no expiry)

### Customization

Expand Down
7 changes: 5 additions & 2 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,15 @@ func (a apiServer) handleCreate(res http.ResponseWriter, r *http.Request) {
}

var (
expiry = cfg.SecretExpiry
expiry = cfg.DefaultSecretExpiry
secret string
)

if !cust.DisableExpiryOverride {
if ev, err := strconv.ParseInt(r.URL.Query().Get("expire"), 10, 64); err == nil && (ev < expiry || cfg.SecretExpiry == 0) {
if cfg.DefaultSecretExpiry == 0 && cfg.MaxSecretExpiry > 0 {
cfg.DefaultSecretExpiry = cfg.MaxSecretExpiry
}
if ev, err := strconv.ParseInt(r.URL.Query().Get("expire"), 10, 64); err == nil && (ev <= cfg.MaxSecretExpiry || cfg.MaxSecretExpiry == 0) {
expiry = ev
}
}
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ services:
# See README for details
REDIS_URL: redis://redis:6379/0
# 168h = 1w
SECRET_EXPIRY: "604800"
MAX_SECRET_EXPIRY: "604800"
# "mem" or "redis" (See README)
STORAGE_TYPE: redis
depends_on:
Expand Down
2 changes: 1 addition & 1 deletion docs/k8s_example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ spec:
value: tcp://ots-redis:6379
- name: REDIS_KEY
value: ots
- name: SECRET_EXPIRY
- name: MAX_SECRET_EXPIRY
value: "172800"
volumeMounts:
- mountPath: /custom
Expand Down
2 changes: 2 additions & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@

// Template variable from Golang process
const maxSecretExpire = {{ .MaxSecretExpiry }}
const defaultSecretExpire = {{ .DefaultSecretExpiry }}

const version = "{{ .Version }}"
window.OTSCustomize = JSON.parse('{{ .Customize.ToJSON }}')
window.useFormalLanguage = {{ .Customize.UseFormalLanguage | mustToJson }}
Expand Down
14 changes: 14 additions & 0 deletions i18n.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ reference:
expire-n-hours: '{n} hour | {n} hours'
expire-n-minutes: '{n} minute | {n} minutes'
expire-n-seconds: '{n} second | {n} seconds'
never: 'never'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename: expire-never (though as this is wrong on a functionality level, we don't need that)

items-explanation:
- You enter a secret into the field on this page
- Your browser encrypts the secret using a generated password
Expand Down Expand Up @@ -62,6 +63,7 @@ translations:
expire-n-hours: '{n} hora | {n} hores'
expire-n-minutes: '{n} minut | {n} minuts'
expire-n-seconds: '{n} segon | {n} segons'
never: 'Mai'
items-explanation:
- Introduïx un secret en el formulari que hi ha en aquesta pàgina
- El teu navegador xifra el secret utilitzant una contrasenya generada
Expand Down Expand Up @@ -106,6 +108,7 @@ translations:
expire-n-hours: '{n} Stunde | {n} Stunden'
expire-n-minutes: '{n} Minute | {n} Minuten'
expire-n-seconds: '{n} Sekunde | {n} Sekunden'
never: 'Nie'
items-explanation:
- Du gibst ein Secret auf dieser Seite ein
- Dein Browser verschlüsselt das Secret mit einem generierten Passwort
Expand Down Expand Up @@ -168,6 +171,7 @@ translations:
expire-n-hours: '{n} hora | {n} horas'
expire-n-minutes: '{n} minuto | {n} minutos'
expire-n-seconds: '{n} segundo | {n} segundos'
never: 'Nunca'
items-explanation:
- Introduce un secreto en el formulario que hay en esta página
- Tu navegador cifra el secreto utilizando una contraseña generada
Expand Down Expand Up @@ -208,6 +212,7 @@ translations:
expire-n-hours: '{n} heure | {n} heures'
expire-n-minutes: '{n} minute | {n} minutes'
expire-n-seconds: '{n} seconde | {n} secondes'
never: 'Jamais'
items-explanation:
- Vous saisissez le secret dans un champ sur cette page
- Votre navigateur chiffre le secret en utilisant un mot de passe généré
Expand Down Expand Up @@ -242,6 +247,7 @@ translations:
expire-n-hours: '{n} stunda | {n} stundas'
expire-n-minutes: '{n} minūte | {n} minūtes'
expire-n-seconds: '{n} sekundes | {n} sekundes'
never: 'Nekad'
items-explanation:
- Tu ievadi ziņu ievades laukā
- Pārlūks nošifrē ziņu ar uzģenerētu paroli
Expand Down Expand Up @@ -279,6 +285,7 @@ translations:
expire-n-hours: '{n} uur | {n} uur'
expire-n-minutes: '{n} minuut | {n} minuten'
expire-n-seconds: '{n} seconde | {n} seconden'
never: 'Nooit'
items-explanation:
- Je vult vertrouwelijke informatie in op deze pagina.
- Je browser versleutelt de ingevulde tekst via een automatisch gegenereerd wachtwoord.
Expand Down Expand Up @@ -323,6 +330,7 @@ translations:
expire-n-hours: '{n} godzina | {n} godzin(y)'
expire-n-minutes: '{n} minuta | {n} minut(y)'
expire-n-seconds: '{n} sekunda | {n} sekund(y)'
never: 'Nigdy'
items-explanation:
- Wpisujesz sekret w pole na tej stronie
- Twoja przeglądarka szyfruje sekret korzystając z wygenerowanego hasła
Expand Down Expand Up @@ -364,6 +372,7 @@ translations:
expire-n-hours: '{n} hora | {n} horas'
expire-n-minutes: '{n} minutos | {n} minutos'
expire-n-seconds: '{n} segundos | {n} segundos'
never: 'Nunca'
items-explanation:
- Você insere o segredo no campo de texto desta página
- Seu navegador criptografa o segredo usando uma senha gerada
Expand Down Expand Up @@ -402,6 +411,7 @@ translations:
expire-n-hours: '{n} час | {n} часов'
expire-n-minutes: '{n} минут | {n} минут'
expire-n-seconds: '{n} секунда | {n} секунд'
never: 'Никогда'
items-explanation:
- Вы вводите секрет в поле на этой странице.
- Ваш браузер шифрует секрет с помощью сгенерированного пароля.
Expand Down Expand Up @@ -445,6 +455,7 @@ translations:
expire-n-hours: '{n} timme | {n} timmar'
expire-n-minutes: '{n} minut | {n} minuter'
expire-n-seconds: '{n} sekund | {n} sekunder'
never: 'Aldrig'
items-explanation:
- Skriv in en hemlighet i rutan nedan
- Din webbläsare krypterar hemligheten med hjälp av ett genererat lösenord
Expand Down Expand Up @@ -485,6 +496,7 @@ translations:
expire-n-hours: '{n} saat | {n} saat'
expire-n-minutes: '{n} dakika | {n} dakika'
expire-n-seconds: '{n} saniye | {n} saniye'
never: 'Asla'
items-explanation:
- Bu sayfadaki alana sırrınızı giriniz
- Internet tarayıcınız oluşturulan şifre yardımı ile sırrınızı enkripte eder
Expand Down Expand Up @@ -522,6 +534,7 @@ translations:
expire-n-hours: '{n} година | {n} годин'
expire-n-minutes: '{n} хвилина | {n} хвилин'
expire-n-seconds: '{n} секунда | {n} секунд'
never: 'Ніколи'
items-explanation:
- Уведіть секрет у поле на цій сторінці
- Ваш браузер шифрує секрет за допомогою згенерованого пароля
Expand Down Expand Up @@ -565,6 +578,7 @@ translations:
expire-n-hours: '{n} 小时 | {n} 小时'
expire-n-minutes: '{n} 分钟 | {n} 分钟'
expire-n-seconds: '{n} 秒 | {n} 秒'
never: '绝不'
items-explanation:
- 您在当前页面的文本框内输入机密内容
- 您的浏览器会生成随机密钥并对机密内容进行加密
Expand Down
36 changes: 20 additions & 16 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ const scriptNonceSize = 32

var (
cfg struct {
Customize string `flag:"customize" default:"" description:"Customize-File to load"`
Listen string `flag:"listen" default:":3000" description:"IP/Port to listen on"`
LogLevel string `flag:"log-level" default:"info" description:"Set log level (debug, info, warning, error)"`
SecretExpiry int64 `flag:"secret-expiry" default:"0" description:"Maximum expiry of the stored secrets in seconds"`
StorageType string `flag:"storage-type" default:"mem" description:"Storage to use for putting secrets to" validate:"nonzero"`
VersionAndExit bool `flag:"version" default:"false" description:"Print version information and exit"`
Customize string `flag:"customize" default:"" description:"Customize-File to load"`
Listen string `flag:"listen" default:":3000" description:"IP/Port to listen on"`
LogLevel string `flag:"log-level" default:"info" description:"Set log level (debug, info, warning, error)"`
MaxSecretExpiry int64 `flag:"max-secret-expiry" default:"0" description:"Maximum expiry of the stored secrets in seconds"`
DefaultSecretExpiry int64 `flag:"default-secret-expiry" default:"0" description:"Default expiry of the stored secrets in seconds"`
StorageType string `flag:"storage-type" default:"mem" description:"Storage to use for putting secrets to" validate:"nonzero"`
VersionAndExit bool `flag:"version" default:"false" description:"Print version information and exit"`
}

assets file_helpers.FSStack
Expand Down Expand Up @@ -154,8 +155,9 @@ func main() {

// Start server
logrus.WithFields(logrus.Fields{
"secret_expiry": time.Duration(cfg.SecretExpiry) * time.Second,
"version": version,
"max_secret_expiry": time.Duration(cfg.MaxSecretExpiry) * time.Second,
"default_secret_expiry": time.Duration(cfg.DefaultSecretExpiry) * time.Second,
"version": version,
}).Info("ots started")

if err = server.ListenAndServe(); err != nil {
Expand Down Expand Up @@ -209,15 +211,17 @@ func handleIndex(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("X-Content-Type-Options", "nosniff")

if err := indexTpl.Execute(w, struct {
Customize customization.Customize
InlineContentNonce string
MaxSecretExpiry int64
Version string
Customize customization.Customize
InlineContentNonce string
MaxSecretExpiry int64
DefaultSecretExpiry int64
Version string
}{
Customize: cust,
InlineContentNonce: inlineContentNonceStr,
MaxSecretExpiry: cfg.SecretExpiry,
Version: version,
Customize: cust,
InlineContentNonce: inlineContentNonceStr,
MaxSecretExpiry: cfg.MaxSecretExpiry,
DefaultSecretExpiry: cfg.DefaultSecretExpiry,
Version: version,
}); err != nil {
http.Error(w, errors.Wrap(err, "executing template").Error(), http.StatusInternalServerError)
return
Expand Down
35 changes: 24 additions & 11 deletions src/components/create.vue
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@
</template>
<script>
/* global maxSecretExpire */
/* global defaultSecretExpire */


import appCrypto from '../crypto.js'
import { bytesToHuman } from '../helpers'
Expand Down Expand Up @@ -153,22 +155,18 @@ export default {
},

expiryChoices() {
const choices = [{ text: this.$t('expire-default'), value: null }]
const choices = [{
text: this.$t('expire-default') + " (" + this.getExpiryLabel(defaultSecretExpire) + ")",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be properly adjusted in the translation, not just appended.

Copy link
Owner

@Luzifer Luzifer Dec 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the label does not solve the issue when values other than 86400, 3600, 60 are set. 129600 will be 2 Days which is wrong.

value: defaultSecretExpire
}]

for (const choice of this.$root.customize.expiryChoices || defaultExpiryChoices) {
if (maxSecretExpire > 0 && choice > maxSecretExpire) {
continue
}

const option = { value: choice }
if (choice >= 86400) {
option.text = this.$tc('expire-n-days', Math.round(choice / 86400))
} else if (choice >= 3600) {
option.text = this.$tc('expire-n-hours', Math.round(choice / 3600))
} else if (choice >= 60) {
option.text = this.$tc('expire-n-minutes', Math.round(choice / 60))
} else {
option.text = this.$tc('expire-n-seconds', choice)
}
option.text = this.getExpiryLabel(choice)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be joined with line above


choices.push(option)
}
Expand Down Expand Up @@ -220,7 +218,7 @@ export default {
fileSize: 0,
secret: '',
securePassword: null,
selectedExpiry: null,
selectedExpiry: defaultSecretExpire,
selectedFileMeta: [],
}
},
Expand Down Expand Up @@ -310,6 +308,21 @@ export default {
return false
},

getExpiryLabel(duration) {
if (duration >= 86400) {
text = this.$tc('expire-n-days', Math.round(duration / 86400))
} else if (duration >= 3600) {
text = this.$tc('expire-n-hours', Math.round(duration / 3600))
} else if (duration >= 60) {
text = this.$tc('expire-n-minutes', Math.round(duration / 60))
} else if (duration > 0) {
text = this.$tc('expire-n-seconds', duration)
} else {
text = this.$t('never')
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix formatting

return text
},

isAcceptedBy(fileMeta, accept) {
if (/^(?:[a-z]+|\*)\/(?:[a-zA-Z0-9.+_-]+|\*)$/.test(accept)) {
// That's likely supposed to be a mime-type
Expand Down