Skip to content

Commit

Permalink
Added memcached support for the new TTL feature (#32)
Browse files Browse the repository at this point in the history
* Reworked the memcached-client to return a static TTL. Adapted the frontend to handle invalid TTLs and use the translation mechanism

* Updated Docker deployment for memcached
  • Loading branch information
TassiloPitrasch authored Dec 13, 2024
1 parent 4c55588 commit f464d9b
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 21 deletions.
32 changes: 21 additions & 11 deletions deploy/docker-compose/insecure-memcached/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
version: "3.0"

services:
memcached:
image: memcached
restart: always
expose:
- "11211"

yopass:
image: jhaals/yopass
image: TassiloPitrasch/yopass:latest
container_name: yopass
restart: always
networks:
- yopass_internal
- yopass_external
ports:
- "127.0.0.1:80:80"
command: "--memcached=memcached:11211 --port 80"
- "80:80"
command: "--database=memcached --memcached=yopass_memcached:11211 --port 80"

memcached:
image: memcached:latest
container_name: yopass_memcached
restart: always
networks:
- yopass_internal

networks:
yopass_internal:
internal: true
yopass_external:
driver: bridge
internal: false
1 change: 1 addition & 0 deletions pkg/server/memcached.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Memcached struct {
// Get key in memcached
func (m *Memcached) Get(key string) (yopass.Secret, error) {
var s yopass.Secret
s.TTL = -1

r, err := m.Client.Get(key)
if err != nil {
Expand Down
5 changes: 4 additions & 1 deletion website/public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@
"secret": {
"titleFile": "File downloaded",
"titleMessage": "Decrypted message",
"buttonCopy": "Copy"
"buttonCopy": "Copy",
"expiresOn": "This secret will expire on {{formattedExpiryDate}}. Be sure to copy/download it until then!",
"expireUnkown": "Could not parse the secret's remaining time-to-live. Be sure to copy/download the secret NOW!",
"oneTime": "This secret is one-time only. It's not stored anywhere anymore. Be sure to copy/download it NOW!"
},
"delete": {
"buttonDelete": "Delete",
Expand Down
5 changes: 1 addition & 4 deletions website/src/displaySecret/DisplaySecret.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,9 @@ const DisplaySecret = () => {
);
}
if (value) {
var expiryDate = new Date();
expiryDate.setMilliseconds(data.ttl / 1000000);

return (
<>
<Secret secret={value.data as string} fileName={value.filename} expiryDate={expiryDate} oneTime={data.one_time}/>
<Secret secret={value.data as string} fileName={value.filename} ttl={data.ttl} oneTime={data.one_time}/>
{data.one_time ? null : <DeleteSecret url={url} />}
</>
);
Expand Down
25 changes: 20 additions & 5 deletions website/src/displaySecret/Secret.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,27 +111,42 @@ const DownloadSecret = ({
const Secret = ({
secret,
fileName,
expiryDate,
ttl,
oneTime,
}: {
readonly secret: string;
readonly fileName?: string;
readonly expiryDate: Date;
readonly ttl: number;
readonly oneTime: boolean;
}) => {
const { t } = useTranslation();
if (! oneTime) {
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const DateTimeFormat = Intl.DateTimeFormat.supportedLocalesOf([i18n.language], {localeMatcher: "lookup"}) ? i18n.language : "en-US";

var formattedDate = new Intl.DateTimeFormat(DateTimeFormat, {
var expiryDate = new Date();
try {

if (ttl < 0) {
throw RangeError;
}
else {
expiryDate.setMilliseconds(ttl / 1000000);
}

var formattedExpiryDate = new Intl.DateTimeFormat(DateTimeFormat, {
dateStyle: 'full',
timeStyle: 'long',
timeZone: timeZone,
}).format(expiryDate);
var notice = "This secret will expire on " + formattedDate + ". Be sure to copy/download it until then!";
var notice = t('secret.expiresOn', {formattedExpiryDate: formattedExpiryDate});;
}
catch(RangeError) {
var notice = t('secret.expireUnkown');
}
}
else {
var notice = "This secret is one-time only. It's not stored anywhere anymore. Be sure to copy/download it NOW!";
var notice = t('secret.oneTime');
}
if (fileName) {
return <DownloadSecret fileName={fileName} secret={secret} notice={notice}/>;
Expand Down

0 comments on commit f464d9b

Please sign in to comment.