Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
23 changes: 23 additions & 0 deletions docs/releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,29 @@

## Version 7

### v7.6.1

Released on June 22nd, 2026

#### Auto rotation of the license key and hot-fixes

This is a hotfix, but it brings a new feature. You can know create a auth token in keygen.lycheeorg.dev and use it in your .env file to automatically rotate your license key.
This is especially useful for our SE and Pro users who want to automate the license key rotation. No longer need to manually update that key when it expires, Lychee will do it for you.

* `new` #4442 : Add auto rotation of the license key provided KEYGEN_API_KEY by @ildyria.
* `fix` #4450 : Add fallback if crypto.randomUUID() is not available by @ildyria.
> In rare cases where users were using Lychee on an ip without https, the upload would not work.
> This is now fixed.
* `fix` #4446 : Fix shared hosting tmp folder issue by @ildyria.
> In some shared hosting environments, the system tmp folder is not writable by the user.
> We provide an alternative temp directory in the storage folder which is writable by the user.
* `fix` #4448 : 10 unlock request per minute by @ildyria.
> A missing rate limit on unlock album was allowing to brute force the unlock code. We now limit the number of requests to 10 per minute.
* `fix` #4449 : Ensure that the user is able to see the photo they are setting as highlighted by @ildyria.
> Provided the attacker knew a photo id, and that the admin had set the configuration to allow highlighting photos without authentication, the attacker could set a photo as highlighted without being able to see it. This is now fixed.

Thanks to @de3erve-hunter for reporting the brute-force and the highlight vulnerability.

### v7.6.0

Released on June 17th, 2026
Expand Down
7 changes: 5 additions & 2 deletions src/components/widgets/Announcement.astro
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
---
import { releases } from '../../pages/roadmap.astro';

const version = releases[0].version.substring(1);

---

Expand All @@ -10,8 +13,8 @@
>NEW</span
>
<a
href="https://github.com/LycheeOrg/Lychee/releases/tag/v7.6.0"
class="text-slate-200 hover:underline dark:text-slate-200 font-medium">Lychee 7.6.0 is now available! »</a
href={`https://github.com/LycheeOrg/Lychee/releases/tag/v${version}`}
class="text-slate-200 hover:underline dark:text-slate-200 font-medium">Lychee {version} is now available! »</a
>
<!-- <a
href="https://github.com/LycheeOrg/Lychee/releases/tag/v6.10.4"
Expand Down
6 changes: 3 additions & 3 deletions src/components/widgets/FeaturesList.astro
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ const {
</thead>
<tbody>
{
specs.map(({ feature, isHeader, isSoon, isPro, values, available, isV7 }) => (
specs.map(({ feature, isHeader, isSoon, isPro, values, available, isV7, isV8 }) => (
<tr class={(isHeader && ' bg-neutral-50 dark:bg-neutral-800') || ''}>
{isHeader && <td class="p-2 font-semibold"><Fragment set:html={feature} />{ isSoon && <Soon/> }{ isPro && <Pro/> }{ isV7 && <Soon tag="v7"/> }</td>}
{isHeader && <td class="p-2 font-semibold"><Fragment set:html={feature} />{ isSoon && <Soon/> }{ isPro && <Pro/> }{ isV7 && <Soon tag="v7"/> }{ isV8 && <Soon tag="v8"/> }</td>}
{isHeader && products.map(() => <td class="p-2 text-center" />)}
{!isHeader && <td class="px-2 text-muted"><Fragment set:html={feature} />{ isSoon && <Soon/> }{ isV7 && <Soon tag="v7"/> }</td> }
{!isHeader && <td class="px-2 text-muted"><Fragment set:html={feature} />{ isSoon && <Soon/> }{ isV7 && <Soon tag="v7"/> }{ isV8 && <Soon tag="v8"/> }</td> }
Comment thread
ildyria marked this conversation as resolved.
{!isHeader && values && (values.map((val) => <td class="px-2 text-muted text-center">{val}</td>))}
{!isHeader && available && !isPro && available.map((yes) => <td class="px-2 text-muted text-center">{yes && <Tick />}</td>)}
{!isHeader && available && isPro && available.map((yes) => <td class="px-2 text-muted text-center">{yes && <Tick classes={{icon_bg: 'bg-amber-200/80 dark:bg-amber-800', icon: 'text-amber-600 dark:text-amber-100'}} />}</td>)}
Expand Down
57 changes: 54 additions & 3 deletions src/pages/get-supporter-edition.astro
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const metadata = {
description: 'Unlimited photo upload.',
},
{
description: '',
description: 'Facial recognition.',
},
],
callToAction: {
Expand Down Expand Up @@ -126,7 +126,7 @@ const metadata = {
title="Full comparison<sup class='text-xl'>*</sup>"
tagline="the essentials and a few more"
products={['Free', 'Lychee <span class="text-sky-600 dark:text-sky-300">SE</span>']}
extra="<sup>*</sup> This table is summary of Lychee's functionalities and does not represent the large amount of configurations available (250+).<br>\
extra="<sup>*</sup> This table is summary of Lychee's functionalities and does not represent the very large amount of configurations available (350+).<br>\
<sup>**</sup> Some languages are still untranslated. Any translations provided via <a class='text-sky-600 dark:text-sky-300 underline hover:text-sky-400 dark:hover:text-sky-500' href='https://weblate.lycheeorg.dev'>weblate</a> will be appreciated.<br>\
<sup>***</sup> This option is not available on <span class='text-sky-600 dark:text-sky-300'>SE</span> as they are already hidden.<br>\
<sup>****</sup> This option requires the <span class='text-sky-600 dark:text-sky-300'>Pro</span> edition of Lychee which is targeted to users who wish to sell their pictures."
Expand Down Expand Up @@ -164,6 +164,12 @@ const metadata = {
feature: 'Hide Lychee <span class="text-sky-600 dark:text-sky-300">SE</span> call for actions <sup>*</sup><sup>*</sup><sup>*</sup>',
available: [true, false],
},
{
feature: 'White label option (remove all mentions of Lychee)',
available: [false, true],
isV7: true,
},


{
feature: 'Photo management',
Expand Down Expand Up @@ -219,6 +225,7 @@ const metadata = {
available: [false, true],
},


{
feature: 'Album management',
isHeader: true,
Expand Down Expand Up @@ -269,6 +276,7 @@ const metadata = {
available: [false, true],
},


{
feature: 'Per Album customizations',
isHeader: true,
Expand Down Expand Up @@ -298,6 +306,7 @@ const metadata = {
available: [false, true],
},


{
feature: 'Flow (display albums in a feed like manner)',
isHeader: true,
Expand Down Expand Up @@ -328,6 +337,7 @@ const metadata = {
available: [false, true],
},


{
feature: 'Tagging',
isHeader: true,
Expand All @@ -353,6 +363,7 @@ const metadata = {
available: [false, true],
},


{
feature: 'Watermarking',
isHeader: true,
Expand Down Expand Up @@ -391,6 +402,7 @@ const metadata = {
available: [false, true],
},


{
feature: 'User management',
isHeader: true,
Expand All @@ -415,6 +427,11 @@ const metadata = {
feature: 'Cross-user sharing',
available: [true, true],
},
{
feature: 'Trust level per user',
available: [true, true],
isV7: true,
},
Comment thread
coderabbitai[bot] marked this conversation as resolved.
{
feature: 'Space usage per user',
available: [false, true],
Expand All @@ -432,6 +449,7 @@ const metadata = {
available: [false, true],
},


{
feature: 'User groups',
isHeader: true,
Expand Down Expand Up @@ -477,6 +495,12 @@ const metadata = {
feature: 'Frame display',
available: [true, true],
},
{
feature: 'Facial Recognition',
available: [true, true],
isSoon: true,
isV8: true,
},
{
feature: 'Personal favourites',
available: [false, true],
Expand All @@ -485,6 +509,18 @@ const metadata = {
feature: 'Renaming rules on import/upload',
available: [false, true],
},
{
feature: 'Contact form',
available: [false, true],
isV7: true,
},
{
feature: 'Sensitive content detection',
available: [false, true],
isSoon: true,
isV8: true,
},


{
feature: 'Sync with local directories',
Expand Down Expand Up @@ -548,6 +584,11 @@ const metadata = {
feature: 'Full manual settings control',
available: [true, true],
},
{
feature: 'Upload moderation',
available: [true, true],
isV7: true,
},
{
feature: 'Statistics on your installation',
available: [false, true],
Expand All @@ -560,7 +601,17 @@ const metadata = {
isV7: true,
},
{
feature: 'Custom pricing (per size & license type)',
feature: 'Custom pricing',
available: [false, true],
isPro: true,
},
{
feature: 'Custom sizes & license type',
available: [false, true],
isPro: true,
},
{
feature: 'Support prints (no integration with printing services)',
available: [false, true],
isPro: true,
},
Expand Down
22 changes: 12 additions & 10 deletions src/pages/roadmap.astro
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ const metadata = {
};

// Release data extracted from releases.md
const releases = [
export const releases = [
{ version: 'v7.6.1', date: 'Jun 22, 2026', title: 'Hotfix', type: 'security', highlights: ['🌟 License key auto-rotations', 'Fix brute force attack on unlock'] },
{ version: 'v7.6.0', date: 'Jun 17, 2026', title: 'Moderation, Custom print sizes and more', type: 'major', highlights: ['Chunked download', 'Moderation features', 'folder upload', '🌟 Custom print sizes (SE)', '🌟 White-label (SE)'] },
{ version: 'v7.5.4', date: 'Apr 8, 2026', title: 'Hotfix', type: 'enhancement', highlights: ['Live vulnerability check', 'Fix listing of shared albums vulnerability'] },
{ version: 'v7.5.3', date: 'Mar 23, 2026', title: 'Hotfix', type: 'security', highlights: ['Fix XSS in RSS feed'] },
Expand Down Expand Up @@ -157,7 +158,7 @@ const getReleaseTypeBadge = (type: string) => {

<Layout metadata={metadata}>
<!-- Page Header -->
<section class="py-16 md:py-20 bg-gradient-to-b from-white to-gray-50 dark:from-gray-900 dark:to-gray-800">
<section class="py-16 md:py-20 bg-linear-to-b from-white to-gray-50 dark:from-gray-900 dark:to-gray-800">
Comment thread
coderabbitai[bot] marked this conversation as resolved.
<div class="mx-auto max-w-3xl px-4 sm:px-6">
<div class="text-center mb-12">
<h1 class="text-4xl md:text-5xl font-bold leading-tight mb-4">
Expand All @@ -172,11 +173,12 @@ const getReleaseTypeBadge = (type: string) => {
<div class="mx-auto max-w-3xl pt-12 px-4 sm:px-6">
<div class="grid grid-cols-2 md:grid-cols-4 gap-8 text-center">
<div class="space-y-2">
<div class="text-4xl font-bold text-primary">7.6.0</div>
<div class="text-4xl font-bold text-primary">{releases[0].version.substring(1)}</div>
<div class="text-sm text-gray-600 dark:text-gray-400 uppercase tracking-wide">Latest Version</div>
</div>
<div class="space-y-2">
<div class="text-4xl font-bold text-primary">123</div>
<div class="text-4xl font-bold text-primary">{releases.length + 17}</div>
<!-- 17 releases on version 3 by us. -->
<div class="text-sm text-gray-600 dark:text-gray-400 uppercase tracking-wide">Total Releases</div>
</div>
<div class="space-y-2">
Expand All @@ -192,7 +194,7 @@ const getReleaseTypeBadge = (type: string) => {
</section>

<!-- Milestones Section -->
<section class="py-16 md:py-20 bg-gradient-to-b from-white to-gray-50 dark:from-gray-900 dark:to-gray-800">
<section class="py-16 md:py-20 bg-linear-to-b from-white to-gray-50 dark:from-gray-900 dark:to-gray-800">
<div class="mx-auto max-w-6xl px-4 sm:px-6">
<!-- Section Header -->
<div class="mb-12 text-center">
Expand Down Expand Up @@ -310,7 +312,7 @@ const getReleaseTypeBadge = (type: string) => {
</section>

<!-- Timeline Section -->
<section class="py-8 md:py-12 bg-gradient-to-b from-white to-gray-50 dark:from-gray-900 dark:to-gray-800">
<section class="py-8 md:py-12 bg-linear-to-b from-white to-gray-50 dark:from-gray-900 dark:to-gray-800">
<div class="mx-auto max-w-3xl px-4 sm:px-6">
<!-- Section Header -->
<div class="mb-8 text-center">
Expand All @@ -325,21 +327,21 @@ const getReleaseTypeBadge = (type: string) => {
<!-- Timeline -->
<div class="relative">
<!-- Timeline Line -->
<div class="absolute left-[10rem] top-4 bottom-0 w-0.5 bg-gradient-to-b from-primary to-blue-300 dark:from-primary dark:to-blue-700" aria-hidden="true"></div>
<div class="absolute left-40 top-4 bottom-0 w-0.5 bg-linear-to-b from-primary to-blue-300 dark:from-primary dark:to-blue-700" aria-hidden="true"></div>

<!-- Timeline Items -->
<div class="space-y-4 md:space-y-6">
{releases.map((release) => (
<div class="relative flex items-start gap-6">
<!-- Date (Left Side) -->
<div class="w-32 text-right flex-shrink-0">
<div class="w-32 text-right shrink-0">
<time class="text-xs font-semibold text-gray-700 dark:text-gray-300">
{release.date}
</time>
</div>

<!-- Timeline Dot -->
<div class="relative flex items-center justify-center flex-shrink-0 mt-1.5">
<div class="relative flex items-center justify-center shrink-0 mt-1.5">
<div class={`w-4 h-4 rounded-full ${getReleaseTypeColor(release.type)} ring-3 ring-white dark:ring-gray-900 shadow-md flex items-center justify-center`}>
<div class="w-1.5 h-1.5 bg-white rounded-full"></div>
</div>
Expand All @@ -363,7 +365,7 @@ const getReleaseTypeBadge = (type: string) => {
<ul class="space-y-0">
{release.highlights.map((highlight) => (
<li class="flex items-start group/item">
<svg class="w-4 h-4 text-primary mt-0.5 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<svg class="w-4 h-4 text-primary mt-0.5 mr-2 shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path>
</svg>
<span class="text-sm text-gray-700 dark:text-gray-300 group-hover/item:text-gray-900 dark:group-hover/item:text-white transition-colors">{highlight}</span>
Expand Down
45 changes: 2 additions & 43 deletions src/pages/support.astro
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
---
// import Features2 from '~/components/widgets/Features2.astro';
// import Features3 from '~/components/widgets/Features3.astro';
// import Features from '~/components/widgets/Features.astro';
import Headline from '~/components/blog/Headline.astro';
import Button from '~/components/ui/Button.astro';
import WidgetWrapper from '~/components/ui/WidgetWrapper.astro';
import CallToAction2 from '~/components/widgets/CallToAction.astro';
import Features from '~/components/widgets/Features.astro';
import Features2 from '~/components/widgets/Features2.astro';
import Features3 from '~/components/widgets/Features3.astro';
import Features5 from '~/components/widgets/Features5.astro';
Expand Down Expand Up @@ -43,38 +37,11 @@ const metadata = {
title="Statistics."
stats={[
{ title: 'Started', amount: '2018' },
{ title: 'Devs', amount: '4' },
{ title: 'Lines of Code', amount: '84K' },
{ title: 'Devs', amount: '5' },
{ title: 'Lines of Code', amount: '300K' },
]}
/>

<!-- June 7th 2025
Using https://github.com/boyter/scc
$/> scc app resources lang database
───────────────────────────────────────────────────────────────────────────────
Language Files Lines Blanks Comments Code Complexity
───────────────────────────────────────────────────────────────────────────────
PHP 1510 95552 9999 26593 58960 1789
Vue 153 15782 1279 357 14146 608
TypeScript 66 9936 683 452 8801 875
Blade template 24 1263 103 20 1140 68
JSON 21 21 0 0 21 0
TypeScript Typings 4 778 2 0 776 295
CSS 3 618 90 38 490 0
SVG 1 15 0 0 15 0
───────────────────────────────────────────────────────────────────────────────
Total 1782 123965 12156 27460 84349 3635
───────────────────────────────────────────────────────────────────────────────
Estimated Cost to Develop (organic) $2,844,325
Estimated Schedule Effort (organic) 20.46 months
Estimated People Required (organic) 12.35
───────────────────────────────────────────────────────────────────────────────
Processed 4742265 bytes, 4.742 megabytes (SI)
───────────────────────────────────────────────────────────────────────────────
-->

<!-- Features3 Widget ************** -->

<Features5
title="Meet the team"
columns={2}
Expand Down Expand Up @@ -119,14 +86,6 @@ Processed 4742265 bytes, 4.742 megabytes (SI)
},
description: 'dev.',
},
// {
// title: 'RonnieTaz (Vicent Simon)',
// image: {
// src: 'https://avatars.githubusercontent.com/u/67832502?v=4',
// alt: 'RonnieTaz',
// },
// description: 'reviewer.',
// },
]}
/>

Expand Down
1 change: 1 addition & 0 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ export interface Features extends Omit<Headline, 'classes'>, Widget {
export interface Spec {
feature: string;
isHeader?: boolean;
isV8?: boolean;
isV7?: boolean;
isSoon?: boolean;
isPro?: boolean;
Expand Down
Loading