From a2bdb00b08156309e26a748f9cf919f26e6ebcf3 Mon Sep 17 00:00:00 2001 From: Antoine Lima Date: Sat, 9 Mar 2024 23:31:33 +0100 Subject: [PATCH 1/9] Fill in the voids the app documentation --- doc/ADMIN.md | 3 --- doc/ADMIN_fr.md | 3 --- doc/DESCRIPTION.md | 10 +++++++++- doc/DESCRIPTION_fr.md | 9 ++++++++- doc/DISCLAIMER.md | 2 ++ doc/DISCLAIMER_fr.md | 2 ++ doc/screenshots/example.jpg | Bin 35451 -> 0 bytes doc/screenshots/main.png | Bin 0 -> 60368 bytes 8 files changed, 21 insertions(+), 8 deletions(-) delete mode 100644 doc/ADMIN.md delete mode 100644 doc/ADMIN_fr.md create mode 100644 doc/DISCLAIMER.md create mode 100644 doc/DISCLAIMER_fr.md delete mode 100644 doc/screenshots/example.jpg create mode 100644 doc/screenshots/main.png diff --git a/doc/ADMIN.md b/doc/ADMIN.md deleted file mode 100644 index c9b5225..0000000 --- a/doc/ADMIN.md +++ /dev/null @@ -1,3 +0,0 @@ -This is a dummy admin doc for this app - -The app install dir is `__INSTALL_DIR__` diff --git a/doc/ADMIN_fr.md b/doc/ADMIN_fr.md deleted file mode 100644 index a138028..0000000 --- a/doc/ADMIN_fr.md +++ /dev/null @@ -1,3 +0,0 @@ -Ceci est une fausse doc d'admin pour cette app - -Le dossier d'install de l'app est `__INSTALL_DIR__` diff --git a/doc/DESCRIPTION.md b/doc/DESCRIPTION.md index 3f2e57a..1b3486f 100644 --- a/doc/DESCRIPTION.md +++ b/doc/DESCRIPTION.md @@ -1 +1,9 @@ -This is a dummy description of this app features + +Crab Fit helps you fit your event around everyone's schedules. +Simply create an event above and send the link to everyone that is participating. +Results update live and you will be able to see a heat-map of when everyone is free. + +## Features + +- Click and slide to select multiple time slots at once. +- Editable using a one-time password diff --git a/doc/DESCRIPTION_fr.md b/doc/DESCRIPTION_fr.md index 13f4b64..3997cb8 100644 --- a/doc/DESCRIPTION_fr.md +++ b/doc/DESCRIPTION_fr.md @@ -1 +1,8 @@ -Ceci est une fausse description des fonctionalités de l'app +Crab Fit vous aide à adapter votre événement aux horaires de chacun·e. +Créez simplement un événement ci-dessus et envoyez le lien à tous les participant·e·s. +Les résultats sont mis à jour en direct et vous pourrez voir une carte thermique montrant quand tout le monde est libre. + +## Fonctionnalités + +- Glisser votre souris pour sélectionner un interval de temps +- Modifiable après coup à l'aide d'un mot de passe à usage unique diff --git a/doc/DISCLAIMER.md b/doc/DISCLAIMER.md new file mode 100644 index 0000000..089da1a --- /dev/null +++ b/doc/DISCLAIMER.md @@ -0,0 +1,2 @@ +- Needs a dedicated domain +- Temporarily downloads and compile cargo for the backend installation diff --git a/doc/DISCLAIMER_fr.md b/doc/DISCLAIMER_fr.md new file mode 100644 index 0000000..77f3f44 --- /dev/null +++ b/doc/DISCLAIMER_fr.md @@ -0,0 +1,2 @@ +- Nécessite un domaine dédié +- Télécharge et compile temporairement un cargo et le backend diff --git a/doc/screenshots/example.jpg b/doc/screenshots/example.jpg deleted file mode 100644 index a1efa1a36d593384df59dc13db03fa83b0436d69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35451 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 UE-)&$xd9C0IsX9d#{5|Pe`qLcKmY&$ diff --git a/doc/screenshots/main.png b/doc/screenshots/main.png new file mode 100644 index 0000000000000000000000000000000000000000..427bafbbcdba7d5e4689339cc6c6cc071eb0cb64 GIT binary patch literal 60368 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 z�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 literal 0 HcmV?d00001 From 0e4e6fb6b876dd790ad3c41ccc51a3b744ebffd3 Mon Sep 17 00:00:00 2001 From: Antoine Lima Date: Sat, 9 Mar 2024 23:33:17 +0100 Subject: [PATCH 2/9] Properly modify the upstream code using patches (thanks to @oiseauroch <3) --- conf/back.env | 1 + scripts/_common.sh | 5 --- .../main-backend_get_port_by_env.patch | 23 ++++++++++++++ ..._make_stats_and_event_paths_relative.patch | 22 +++++++++++++ .../main-remove_vercel_analytics.patch | 31 +++++++++++++++++++ 5 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 sources/patches/main-backend_get_port_by_env.patch create mode 100644 sources/patches/main-frontend_make_stats_and_event_paths_relative.patch create mode 100644 sources/patches/main-remove_vercel_analytics.patch diff --git a/conf/back.env b/conf/back.env index 6b66c48..64bc669 100644 --- a/conf/back.env +++ b/conf/back.env @@ -1,2 +1,3 @@ FRONTEND_URL=https://__DOMAIN__/ DATABASE_URL=postgres://__DB_USER__:__DB_PWD__@localhost:5432/__DB_NAME__ +PORT=__PORT_API__ diff --git a/scripts/_common.sh b/scripts/_common.sh index 500756e..f4854d2 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -15,11 +15,6 @@ function build_backend # The cargo version packaged with debian (currently 11) is too old and results in errors.. # Thus the latest version is manually installed alongside the application for the moment pushd $install_dir/api - # The API port is currently hard-coded instead of being in a .env - # TODO: MR to the upstream - # In the meantime, lets do some sed! - sed -i "s/3000/$port_api/g" src/main.rs - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rustup.sh ynh_exec_warn_less ynh_exec_as "$app" \ RUSTUP_HOME=$install_dir/api/.rustup \ diff --git a/sources/patches/main-backend_get_port_by_env.patch b/sources/patches/main-backend_get_port_by_env.patch new file mode 100644 index 0000000..19eeccc --- /dev/null +++ b/sources/patches/main-backend_get_port_by_env.patch @@ -0,0 +1,23 @@ +diff --git a/api/src/main.rs b/api/src/main.rs +index da3e2c3..3ebd00e 100644 +--- a/api/src/main.rs ++++ b/api/src/main.rs +@@ -60,6 +60,9 @@ async fn main() { + .unwrap(), + ); + ++ let port = env::var("PORT").unwrap_or("3000".to_string()); ++ let port = port.parse::().expect("Unable to parse port"); ++ + // Rate limiting configuration (using tower_governor) + // From the docs: Allows bursts with up to 20 requests and replenishes + // one element after 500ms, based on peer IP. +@@ -99,7 +102,7 @@ async fn main() { + .layer(rate_limit) + .layer(TraceLayer::new_for_http()); + +- let addr = SocketAddr::from(([0, 0, 0, 0], 3000)); ++ let addr = SocketAddr::from(([0, 0, 0, 0], port)); + + println!( + "🦀 Crab Fit API listening at http://{} in {} mode", diff --git a/sources/patches/main-frontend_make_stats_and_event_paths_relative.patch b/sources/patches/main-frontend_make_stats_and_event_paths_relative.patch new file mode 100644 index 0000000..45036e8 --- /dev/null +++ b/sources/patches/main-frontend_make_stats_and_event_paths_relative.patch @@ -0,0 +1,22 @@ +diff --git a/frontend/src/config/api.ts b/frontend/src/config/api.ts +index 312b092..6c11328 100644 +--- a/frontend/src/config/api.ts ++++ b/frontend/src/config/api.ts +@@ -70,11 +70,11 @@ const post = async (url: string, schema: S, input: unknown, + } + + // Get +-export const getStats = () => get('/stats', StatsResponse, undefined, { revalidate: 60 }) +-export const getEvent = (eventId: string) => get(`/event/${eventId}`, EventResponse) +-export const getPeople = (eventId: string) => get(`/event/${eventId}/people`, PersonResponse.array()) +-export const getPerson = (eventId: string, personName: string, password?: string) => get(`/event/${eventId}/people/${personName}`, PersonResponse, password && btoa(password)) ++export const getStats = () => get('stats', StatsResponse, undefined, { revalidate: 60 }) ++export const getEvent = (eventId: string) => get(`event/${eventId}`, EventResponse) ++export const getPeople = (eventId: string) => get(`event/${eventId}/people`, PersonResponse.array()) ++export const getPerson = (eventId: string, personName: string, password?: string) => get(`event/${eventId}/people/${personName}`, PersonResponse, password && btoa(password)) + + // Post +-export const createEvent = (input: EventInput) => post('/event', EventResponse, EventInput.parse(input)) +-export const updatePerson = (eventId: string, personName: string, input: PersonInput, password?: string) => post(`/event/${eventId}/people/${personName}`, PersonResponse, PersonInput.parse(input), password && btoa(password), 'PATCH') ++export const createEvent = (input: EventInput) => post('event', EventResponse, EventInput.parse(input)) ++export const updatePerson = (eventId: string, personName: string, input: PersonInput, password?: string) => post(`event/${eventId}/people/${personName}`, PersonResponse, PersonInput.parse(input), password && btoa(password), 'PATCH') diff --git a/sources/patches/main-remove_vercel_analytics.patch b/sources/patches/main-remove_vercel_analytics.patch new file mode 100644 index 0000000..84ddb67 --- /dev/null +++ b/sources/patches/main-remove_vercel_analytics.patch @@ -0,0 +1,31 @@ +diff --git a/frontend/package.json b/frontend/package.json +index 486af7a..4537034 100644 +--- a/frontend/package.json ++++ b/frontend/package.json +@@ -15,7 +15,6 @@ + "@giraugh/tools": "^1.6.0", + "@js-temporal/polyfill": "^0.4.4", + "@microsoft/microsoft-graph-client": "^3.0.5", +- "@vercel/analytics": "^1.0.1", + "accept-language": "^3.0.18", + "chroma.ts": "^1.0.10", + "hue-map": "^1.0.0", +diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx +index d4c1466..83a99c0 100644 +--- a/frontend/src/app/layout.tsx ++++ b/frontend/src/app/layout.tsx +@@ -1,6 +1,5 @@ + import { Metadata } from 'next' + import { Karla } from 'next/font/google' +-import { Analytics } from '@vercel/analytics/react' + + import Egg from '/src/components/Egg/Egg' + import Settings from '/src/components/Settings/Settings' +@@ -44,7 +43,6 @@ const RootLayout = async ({ children }: { children: React.ReactNode }) => { + + {children} + +- + + + } From 1180a56d1e58e447f32861afa95089e87020a00a Mon Sep 17 00:00:00 2001 From: Antoine Lima Date: Sat, 9 Mar 2024 23:56:08 +0100 Subject: [PATCH 3/9] Fix first round of CI warnings --- LICENSE | 676 ++++++++++++++++++++++++++++++++++++++++++++- manifest.toml | 5 +- scripts/_common.sh | 5 - scripts/install | 3 +- scripts/restore | 7 +- scripts/upgrade | 6 +- tests.toml | 3 + tests.toml.example | 55 ---- 8 files changed, 684 insertions(+), 76 deletions(-) create mode 100644 tests.toml delete mode 100644 tests.toml.example diff --git a/LICENSE b/LICENSE index 2026412..c3f5b52 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,674 @@ -File containing the license of your package. +GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 -More information here: -https://choosealicense.com/ +Copyright (C) 2007 Free Software Foundation, Inc. +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + + Preamble + +The GNU General Public License is a free, copyleft license for +software and other kinds of works. + +The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + +Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + +Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + +0. Definitions. + +"This License" refers to version 3 of the GNU General Public License. + +"Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + +"The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + +To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + +A "covered work" means either the unmodified Program or a work based +on the Program. + +To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + +To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + +1. Source Code. + +The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + +A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + +The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + +The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + +The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + +The Corresponding Source for a work in source code form is that +same work. + +2. Basic Permissions. + +All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. + +No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + +When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + +4. Conveying Verbatim Copies. + +You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. + +You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified +it, and giving a relevant date. + +b) The work must carry prominent notices stating that it is +released under this License and any conditions added under section +7. This requirement modifies the requirement in section 4 to +"keep intact all notices". + +c) You must license the entire work, as a whole, under this +License to anyone who comes into possession of a copy. This +License will therefore apply, along with any applicable section 7 +additional terms, to the whole of the work, and all its parts, +regardless of how they are packaged. This License gives no +permission to license the work in any other way, but it does not +invalidate such permission if you have separately received it. + +d) If the work has interactive user interfaces, each must display +Appropriate Legal Notices; however, if the Program has interactive +interfaces that do not display Appropriate Legal Notices, your +work need not make them do so. + +A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + +6. Conveying Non-Source Forms. + +You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + +a) Convey the object code in, or embodied in, a physical product +(including a physical distribution medium), accompanied by the +Corresponding Source fixed on a durable physical medium +customarily used for software interchange. + +b) Convey the object code in, or embodied in, a physical product +(including a physical distribution medium), accompanied by a +written offer, valid for at least three years and valid for as +long as you offer spare parts or customer support for that product +model, to give anyone who possesses the object code either (1) a +copy of the Corresponding Source for all the software in the +product that is covered by this License, on a durable physical +medium customarily used for software interchange, for a price no +more than your reasonable cost of physically performing this +conveying of source, or (2) access to copy the +Corresponding Source from a network server at no charge. + +c) Convey individual copies of the object code with a copy of the +written offer to provide the Corresponding Source. This +alternative is allowed only occasionally and noncommercially, and +only if you received the object code with such an offer, in accord +with subsection 6b. + +d) Convey the object code by offering access from a designated +place (gratis or for a charge), and offer equivalent access to the +Corresponding Source in the same way through the same place at no +further charge. You need not require recipients to copy the +Corresponding Source along with the object code. If the place to +copy the object code is a network server, the Corresponding Source +may be on a different server (operated by you or a third party) +that supports equivalent copying facilities, provided you maintain +clear directions next to the object code saying where to find the +Corresponding Source. Regardless of what server hosts the +Corresponding Source, you remain obligated to ensure that it is +available for as long as needed to satisfy these requirements. + +e) Convey the object code using peer-to-peer transmission, provided +you inform other peers where the object code and Corresponding +Source of the work are being offered to the general public at no +charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + +A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + +"Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + +If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + +The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + +7. Additional Terms. + +"Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the +terms of sections 15 and 16 of this License; or + +b) Requiring preservation of specified reasonable legal notices or +author attributions in that material or in the Appropriate Legal +Notices displayed by works containing it; or + +c) Prohibiting misrepresentation of the origin of that material, or +requiring that modified versions of such material be marked in +reasonable ways as different from the original version; or + +d) Limiting the use for publicity purposes of names of licensors or +authors of the material; or + +e) Declining to grant rights under trademark law for use of some +trade names, trademarks, or service marks; or + +f) Requiring indemnification of licensors and authors of that +material by anyone who conveys the material (or modified versions of +it) with contractual assumptions of liability to the recipient, for +any liability that these contractual assumptions directly impose on +those licensors and authors. + +All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + +8. Termination. + +You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + +However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + +9. Acceptance Not Required for Having Copies. + +You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. + +Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + +An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + +11. Patents. + +A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + +A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + +In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + +If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + +A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. + +If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. + +Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + +14. Revised Versions of this License. + +The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + +Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + +15. Disclaimer of Warranty. + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. + +If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + +Copyright (C) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + +If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) +This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. +This is free software, and you are welcome to redistribute it +under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + +You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + +The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/manifest.toml b/manifest.toml index e80e2b9..02c786b 100644 --- a/manifest.toml +++ b/manifest.toml @@ -13,9 +13,8 @@ maintainers = ["limaanto"] license = "GPLv3" website = "https://crab.fit" demo = "https://crab.fit" -#FIXME: Find where these two values will end up -#admindoc = "https://yunohost.org/packaging_apps" -#userdoc = "https://yunohost.org/apps" +admindoc = "https://github.com/GRA0007/crab.fit" +userdoc = "https://github.com/GRA0007/crab.fit" code = "https://github.com/GRA0007/crab.fit" [integration] diff --git a/scripts/_common.sh b/scripts/_common.sh index f4854d2..e838248 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -39,11 +39,6 @@ function build_frontend ynh_script_progression --message="Building crabfit frontend..." --weight=1 pushd $install_dir/frontend - # Paths are currently absolute, which breaks having a /api/ path prefix - # TODO: MR to the upstream - sed -i "s/\/event/event/g" $install_dir/frontend/src/config/api.ts - sed -i "s/\/stats/stats/g" $install_dir/frontend/src/config/api.ts - ynh_exec_warn_less env "$ynh_node_load_PATH" $nodejs_path/corepack enable ynh_exec_warn_less ynh_exec_as "$app" env "$ynh_node_load_PATH" $nodejs_path/yarn install --production --frozen-lockfile ynh_exec_warn_less ynh_exec_as "$app" env "$ynh_node_load_PATH" $ynh_npm run build diff --git a/scripts/install b/scripts/install index ada5e8e..b7aaf03 100755 --- a/scripts/install +++ b/scripts/install @@ -18,7 +18,8 @@ ynh_script_progression --message="Setting up source files..." --weight=1 # Download, check integrity, uncompress and patch the source from app.src ynh_setup_source --dest_dir="$install_dir" -chown -R $app:www-data "$install_dir" +chown -R $app:$app "$install_dir" +chmod -R o-rwx "$install_dir" ynh_install_nodejs --nodejs_version=$nodejs_version ynh_use_nodejs diff --git a/scripts/restore b/scripts/restore index 83cb4dc..ac8cc74 100755 --- a/scripts/restore +++ b/scripts/restore @@ -19,11 +19,8 @@ ynh_install_nodejs --nodejs_version=$nodejs_version ynh_use_nodejs ynh_restore_file --origin_path="$install_dir" - -# $install_dir will automatically be initialized with some decent -# permission by default ... however, you may need to recursively reapply -# ownership to all files such as after the ynh_setup_source step -chown -R $app:www-data "$install_dir" +chown -R $app:$app "$install_dir" +chmod -R o-rwx "$install_dir" #================================================= # RESTORE THE POSTGRESQL DATABASE diff --git a/scripts/upgrade b/scripts/upgrade index ee36008..799aed9 100755 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -77,10 +77,8 @@ then ynh_setup_source --dest_dir="$install_dir" fi -# $install_dir will automatically be initialized with some decent -# permission by default ... however, you may need to recursively reapply -# ownership to all files such as after the ynh_setup_source step -chown -R $app:www-data "$install_dir" +chown -R $app:$app "$install_dir" +chmod -R o-rwx "$install_dir" #================================================= # REAPPLY SYSTEM CONFIGURATIONS diff --git a/tests.toml b/tests.toml new file mode 100644 index 0000000..cbbeef1 --- /dev/null +++ b/tests.toml @@ -0,0 +1,3 @@ +test_format = 1.0 + +[default] diff --git a/tests.toml.example b/tests.toml.example deleted file mode 100644 index 3a732e4..0000000 --- a/tests.toml.example +++ /dev/null @@ -1,55 +0,0 @@ -test_format = 1.0 - -[default] - - # ------------ - # Tests to run - # ------------ - - # NB: the tests to run are automatically deduced by the CI script according to the - # content of the app's manifest. The declarations below allow to customize which - # tests are ran, possibly add special test suite to test special args, or - # declare which commits to test upgrade from. - # - # You can also decide (though this is discouraged!) to ban/ignore some tests, - - exclude = ["install.private", "install.multi"] # The test IDs to be used in only/exclude statements are: install.root, install.subdir, install.nourl, install.multi, backup_restore, upgrade, upgrade.someCommitId change_url - # NB: you should NOT need this except if you really have a good reason... - - # For special usecases, sometimes you need to setup other things on the machine - # prior to installing the app (such as installing another app) - # (Remove this key entirely if not needed) - preinstall = """ - sudo yunohost app install foobar - sudo yunohost user list - """ - - # ------------------------------- - # Default args to use for install - # ------------------------------- - - # By default, the CI will automagically fill the 'standard' args - # such as domain, path, admin, is_public and password with relevant values - # and also install args with a "default" provided in the manifest.. - # It should only make sense to declare custom args here for args with no default values - - args.language = "fr_FR" # NB: you should NOT need those lines unless for custom questions with no obvious/default value - args.multisite = 0 - - # ------------------------------- - # Commits to test upgrade from - # ------------------------------- - - test_upgrade_from.00a1a6e7.name = "Upgrade from 5.4" - test_upgrade_from.00a1a6e7.args.foo = "bar" - - -# This is an additional test suite -[some_additional_testsuite] - - # On additional tests suites, you can decide to run only specific tests - - only = ["install.subdir"] - - args.language = "en_GB" - args.multisite = 1 From 6e25ff7dc63dda5cc0031efb609ec0fb15cf3249 Mon Sep 17 00:00:00 2001 From: Antoine Lima Date: Sun, 10 Mar 2024 00:02:42 +0100 Subject: [PATCH 4/9] Ignore the multi-path test to fix the CI --- config_panel.toml.example | 302 -------------------------------------- manifest.toml | 2 - tests.toml | 2 + 3 files changed, 2 insertions(+), 304 deletions(-) delete mode 100644 config_panel.toml.example diff --git a/config_panel.toml.example b/config_panel.toml.example deleted file mode 100644 index ed147af..0000000 --- a/config_panel.toml.example +++ /dev/null @@ -1,302 +0,0 @@ - -## Config panel are available from webadmin > Apps > YOUR_APP > Config Panel Button -## Those panels let user configure some params on their apps using a friendly interface, -## and remove the need to manually edit files from the command line. - -## From a packager perspective, this .toml is coupled to the scripts/config script, -## which may be used to define custom getters/setters. However, most use cases -## should be covered automagically by the core, thus it may not be necessary -## to define a scripts/config at all! - -## ----------------------------------------------------------------------------- -## IMPORTANT: In accordance with YunoHost's spirit, please keep things simple and -## do not overwhelm the admin with tons of misunderstandable or advanced settings. -## ----------------------------------------------------------------------------- - -## The top level describe the entire config panels screen. - -## The version is a required property. -## Here a small reminder to associate config panel version with YunoHost version -## | Config | YNH | Config panel small change log | -## | ------ | --- | ------------------------------------------------------- | -## | 0.1 | 3.x | 0.1 config script not compatible with YNH >= 4.3 | -## | 1.0 | 4.3.x | The new config panel system with 'bind' property | -version = "1.0" - -## (optional) i18n property let you internationalize questions, however this feature -## is only available in core configuration panel (like yunohost domain config). -## So in app config panel this key is ignored for now, but you can internationalize -## by using a lang dictionary (see property name bellow) -# i18n = "prefix_translation_key" - -################################################################################ -#### ABOUT PANELS -################################################################################ - -## The next level describes web admin panels -## You have to choose an ID for each panel, in this example the ID is "main" -## Keep in mind this ID will be used in CLI to refer to your question, so choose -## something short and meaningfull. -## In the webadmin, each panel corresponds to a distinct tab / form -[main] - -## Define the label for your panel -## Internationalization works similarly to the 'description' and 'ask' questions in the manifest -# name.en = "Main configuration" -# name.fr = "Configuration principale" - -## (optional) If you need to trigger a service reload-or-restart after the user -## change a question in this panel, you can add your service in the list. -services = ["__APP__"] -# or services = ["nginx", "__APP__"] to also reload-or-restart nginx - -## (optional) This help properties is a short help displayed on the same line -## than the panel title but not displayed in the tab. -# help = "" - - ############################################################################ - #### ABOUT SECTIONS - ############################################################################ - - ## A panel is composed of one or several sections. - ## - ## Sections are meant to group questions together when they correspond to - ## a same subtopic. This impacts the rendering in terms of CLI prompts - ## and HTML forms - ## - ## You should choose an ID for your section, and prefix it with the panel ID - ## (Be sure to not make a typo in the panel ID, which would implicitly create - ## an other entire panel) - ## - ## We use the context of pepettes_ynh as an example, - ## which is a simple donation form app written in python, - ## and for which the admin will want to edit the configuration - [main.customization] - - ## (optional) Defining a proper title for sections is not mandatory - ## and depends on the exact rendering you're aiming for the CLI / webadmin - name = "" - - ## (optional) This help properties is a short help displayed on the same line - ## than the section title, meant to provide additional details - # help = "" - - ## (optional) As for panel, you can specify to trigger a service - ## reload-or-restart after the user change a question in this section. - ## This property is added to the panel property, it doesn't deactivate it. - ## So no need to replicate, the service list from panel services property. - # services = [] - - ## (optional) By default all questions are optionals, but you can specify a - ## default behaviour for question in the section - optional = false - - ## (optional) It's also possible with the 'visible' property to only - ## display the section depending on the user's answers to previous questions. - ## - ## Be careful that the 'visible' property should only refer to **previous** questions - ## Hence, it should not make sense to have a "visible" property on the very first section. - ## - ## Also, keep in mind that this feature only works in the webadmin and not in CLI - ## (therefore a user could be prompted in CLI for a question that may not be relevant) - # visible = true - - ######################################################################## - #### ABOUT QUESTIONS - ######################################################################## - - ## A section is compound of one or several questions. - - ## --------------------------------------------------------------------- - ## IMPORTANT: as for panel and section you have to choose an ID, but this - ## one should be unique in all this document, even if the question is in - ## an other panel. - ## --------------------------------------------------------------------- - - ## You can use same questions types and properties than in manifest.yml - ## install part. However, in YNH 4.3, a lot of change has been made to - ## extend availables questions types list. - ## See: TODO DOC LINK - - [main.customization.project_name] - - ## (required) The ask property is equivalent to the ask property in - ## the manifest. However, in config panels, questions are displayed on the - ## left side and therefore have less space to be rendered. Therefore, - ## it is better to use a short question, and use the "help" property to - ## provide additional details if necessary. - ask.en = "Name of the project" - - ## (required) The type property indicates how the question should be - ## displayed, validated and managed. Some types have specific properties. - ## - ## Types available: string, boolean, number, range, text, password, path - ## email, url, date, time, color, select, domain, user, tags, file. - ## - ## For a complete list with specific properties, see: TODO DOC LINK - type = "string" - - ######################################################################## - #### ABOUT THE BIND PROPERTY - ######################################################################## - - ## (recommended) 'bind' property is a powerful feature that let you - ## configure how and where the data will be read, validated and written. - - ## By default, 'bind property is in "settings" mode, it means it will - ## **only** read and write the value in application settings file. - ## bind = "settings" - - ## However, settings usually correspond to key/values in actual app configurations - ## Hence, a more useful mode is to have bind = ":FILENAME". In that case, YunoHost - ## will automagically find a line with "KEY=VALUE" in FILENAME - ## (with the adequate separator between KEY and VALUE) - ## - ## YunoHost will then use this value for the read/get operation. - ## During write/set operations, YunoHost will overwrite the value - ## in **both** FILENAME and in the app's settings.yml - - ## Configuration file format supported: yaml, toml, json, ini, env, php, - ## python. The feature probably works with others formats, but should be tested carefully. - - ## Note that this feature only works with relatively simple cases - ## such as `KEY: VALUE`, but won't properly work with - ## complex data structures like multilin array/lists or dictionnaries. - ## It also doesn't work with XML format, custom config function call, php define(), ... - - ## More info on TODO - # bind = ":/var/www/__APP__/settings.py" - - - ## By default, bind = ":FILENAME" will use the question ID as KEY - ## ... but the question ID may sometime not be the exact KEY name in the configuration file. - ## - ## In particular, in pepettes, the python variable is 'name' and not 'project_name' - ## (c.f. https://github.com/YunoHost-Apps/pepettes_ynh/blob/5cc2d3ffd6529cc7356ff93af92dbb6785c3ab9a/conf/settings.py##L11 ) - ## - ## In that case, the key name can be specified before the column ':' - - bind = "name:/var/www/__APP__/settings.py" - - ## --------------------------------------------------------------------- - ## IMPORTANT: other 'bind' mode exists: - ## - ## bind = "FILENAME" (with no column character before FILENAME) - ## may be used to bind to the **entire file content** (instead of a single KEY/VALUE) - ## This could be used to expose an entire configuration file, or binary files such as images - ## For example: - ## bind = "/var/www/__APP__/img/logo.png" - ## - ## bind = "null" can be used to disable reading / writing in settings. - ## This creates sort of a "virtual" or "ephemeral" question which is not related to any actual setting - ## In this mode, you are expected to define custom getter/setters/validators in scripts/config: - ## - ## getter: get__QUESTIONID() - ## setter: set__QUESTIONID() - ## validator: validate__QUESTIONID() - ## - ## You can also specify a common getter / setter / validator, with the - ## function 'bind' mode, for example here it will try to run - ## get__array_settings() first. - # bind = "array_settings()" - ## --------------------------------------------------------------------- - - ## --------------------------------------------------------------------- - ## IMPORTANT: with the exception of bind=null questions, - ## question IDs should almost **always** correspond to an app setting - ## initialized / reused during install/upgrade. - ## Not doing so may result in inconsistencies between the config panel mechanism - ## and the use of ynh_add_config - ## --------------------------------------------------------------------- - - ######################################################################## - #### OTHER GENERIC PROPERTY FOR QUESTIONS - ######################################################################## - - ## (optional) An help text for the question - help = "Fill the name of the project which will received donation" - - ## (optional) An example display as placeholder in web form - # example = "YunoHost" - - ## (optional) set to true in order to redact the value in operation logs - # redact = false - - ## (optional) for boolean questions you can specify replacement values - ## bound to true and false, in case property is bound to config file - # useful if bound property in config file expects something else than integer 1 - yes = "Enable" - # useful if bound property in config file expects something else than integer 0 - no = "Disable" - - ## (optional) A validation pattern - ## --------------------------------------------------------------------- - ## IMPORTANT: your pattern should be between simple quote, not double. - ## --------------------------------------------------------------------- - pattern.regexp = '^\w{3,30}$' - pattern.error = "The name should be at least 3 chars and less than 30 chars. Alphanumeric chars are accepted" - - ## Note: visible and optional properties are also available for questions - - - [main.customization.contact_url] - ask = "Contact url" - type = "url" - example = "mailto: contact@example.org" - help = "mailto: accepted" - pattern.regexp = '^mailto:[^@]+@[^@]+|https://$' - pattern.error = "Should be https or mailto:" - bind = ":/var/www/__APP__/settings.py" - - [main.customization.logo] - ask = "Logo" - type = "file" - accept = ".png" - help = "Fill with an already resized logo" - bind = "__INSTALL_DIR__/img/logo.png" - - [main.customization.favicon] - ask = "Favicon" - type = "file" - accept = ".png" - help = "Fill with an already sized favicon" - bind = "__INSTALL_DIR__/img/favicon.png" - - - [main.stripe] - name = "Stripe general info" - optional = false - - # The next alert is overwrited with a getter from the config script - [main.stripe.amount] - ask = "Donation in the month : XX € - type = "alert" - style = "success" - - [main.stripe.publishable_key] - ask = "Publishable key" - type = "string" - redact = true - help = "Indicate here the stripe publishable key" - bind = ":/var/www/__APP__/settings.py" - - [main.stripe.secret_key] - ask = "Secret key" - type = "string" - redact = true - help = "Indicate here the stripe secret key" - bind = ":/var/www/__APP__/settings.py" - - [main.stripe.prices] - ask = "Prices ID" - type = "tags" - help = """\ - Indicates here the prices ID of donation products you created in stripe interfaces. \ - Go on [Stripe products](https://dashboard.stripe.com/products) to create those donation products. \ - Fill it tag with 'FREQUENCY/CURRENCY/PRICE_ID' \ - FREQUENCY: 'one_time' or 'recuring' \ - CURRENCY: 'EUR' or 'USD' \ - PRICE_ID: ID from stripe interfaces starting with 'price_' \ - """ - pattern.regexp = '^(one_time|recuring)/(EUR|USD)/price_.*$' - pattern.error = "Please respect the format describe in help text for each price ID" diff --git a/manifest.toml b/manifest.toml index 02c786b..1f89d04 100644 --- a/manifest.toml +++ b/manifest.toml @@ -31,12 +31,10 @@ ram.runtime = "100M" [install.domain] type = "domain" - [install.init_main_permission] type = "group" default = "visitors" - [resources] [resources.sources] [resources.sources.main] diff --git a/tests.toml b/tests.toml index cbbeef1..1165e3e 100644 --- a/tests.toml +++ b/tests.toml @@ -1,3 +1,5 @@ test_format = 1.0 [default] + +exclude = ["install.subdir"] From 304f2640518ccb0f6e7a0bcf9e04ed7d31e09879 Mon Sep 17 00:00:00 2001 From: Antoine Lima Date: Sun, 10 Mar 2024 00:12:56 +0100 Subject: [PATCH 5/9] Move the ynh_script_progression outside of _common.sh --- scripts/_common.sh | 4 ---- scripts/install | 2 ++ scripts/upgrade | 2 ++ 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/_common.sh b/scripts/_common.sh index e838248..77f4842 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -10,8 +10,6 @@ export nodejs_version="18" #================================================= function build_backend { - ynh_script_progression --message="Building crabfit backend..." --weight=1 - # The cargo version packaged with debian (currently 11) is too old and results in errors.. # Thus the latest version is manually installed alongside the application for the moment pushd $install_dir/api @@ -36,8 +34,6 @@ function build_backend function build_frontend { - ynh_script_progression --message="Building crabfit frontend..." --weight=1 - pushd $install_dir/frontend ynh_exec_warn_less env "$ynh_node_load_PATH" $nodejs_path/corepack enable ynh_exec_warn_less ynh_exec_as "$app" env "$ynh_node_load_PATH" $nodejs_path/yarn install --production --frozen-lockfile diff --git a/scripts/install b/scripts/install index b7aaf03..866385d 100755 --- a/scripts/install +++ b/scripts/install @@ -60,11 +60,13 @@ chown $app:$app "$install_dir/api/.env" #================================================= # BUILD BACKEND #================================================= +ynh_script_progression --message="Building crabfit backend..." --weight=10 build_backend #================================================= # BUILD FRONTEND #================================================= +ynh_script_progression --message="Building crabfit frontend..." --weight=2 build_frontend #================================================= diff --git a/scripts/upgrade b/scripts/upgrade index 799aed9..70e05f9 100755 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -132,11 +132,13 @@ chown $app:$app "$install_dir/api/.env" #================================================= # BUILD BACKEND #================================================= +ynh_script_progression --message="Building crabfit backend..." --weight=10 build_backend #================================================= # BUILD FRONTEND #================================================= +ynh_script_progression --message="Building crabfit frontend..." --weight=2 build_frontend #================================================= From e894a8bbd833de9795b846ee78e88edfbb2b859f Mon Sep 17 00:00:00 2001 From: Antoine Lima Date: Sun, 10 Mar 2024 00:13:46 +0100 Subject: [PATCH 6/9] Use a SPDX standard name for our license --- manifest.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.toml b/manifest.toml index 1f89d04..0013b2e 100644 --- a/manifest.toml +++ b/manifest.toml @@ -10,7 +10,7 @@ version = "1.0~ynh1" maintainers = ["limaanto"] [upstream] -license = "GPLv3" +license = "GPL-3.0-only" website = "https://crab.fit" demo = "https://crab.fit" admindoc = "https://github.com/GRA0007/crab.fit" From 9d21a77db2a5cc069903252715a9d5f11686d2f2 Mon Sep 17 00:00:00 2001 From: Antoine Lima Date: Sun, 10 Mar 2024 00:14:21 +0100 Subject: [PATCH 7/9] Update the backend patch to listen only on the loopback --- sources/patches/main-backend_get_port_by_env.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/patches/main-backend_get_port_by_env.patch b/sources/patches/main-backend_get_port_by_env.patch index 19eeccc..cef476f 100644 --- a/sources/patches/main-backend_get_port_by_env.patch +++ b/sources/patches/main-backend_get_port_by_env.patch @@ -17,7 +17,7 @@ index da3e2c3..3ebd00e 100644 .layer(TraceLayer::new_for_http()); - let addr = SocketAddr::from(([0, 0, 0, 0], 3000)); -+ let addr = SocketAddr::from(([0, 0, 0, 0], port)); ++ let addr = SocketAddr::from(([127, 0, 0, 1], port)); println!( "🦀 Crab Fit API listening at http://{} in {} mode", From 30a1bbc0aa6f05f071ba31fc865f386b4e6ee78d Mon Sep 17 00:00:00 2001 From: Antoine Lima Date: Sun, 10 Mar 2024 10:19:56 +0100 Subject: [PATCH 8/9] Activate JS in the upgrade script --- scripts/upgrade | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/upgrade b/scripts/upgrade index 70e05f9..089da17 100755 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -77,6 +77,9 @@ then ynh_setup_source --dest_dir="$install_dir" fi +ynh_install_nodejs --nodejs_version=$nodejs_version +ynh_use_nodejs + chown -R $app:$app "$install_dir" chmod -R o-rwx "$install_dir" From a6628075bb752ef9b5e8b772d7a39883ee14fdc5 Mon Sep 17 00:00:00 2001 From: oiseauroch Date: Sun, 10 Mar 2024 11:10:20 +0100 Subject: [PATCH 9/9] rebuild only if upgrade is app --- scripts/upgrade | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/scripts/upgrade b/scripts/upgrade index 089da17..2515fab 100755 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -75,14 +75,14 @@ then # Download, check integrity, uncompress and patch the source from app.src ynh_setup_source --dest_dir="$install_dir" + chown -R $app:$app "$install_dir" + chmod -R o-rwx "$install_dir" + fi ynh_install_nodejs --nodejs_version=$nodejs_version ynh_use_nodejs -chown -R $app:$app "$install_dir" -chmod -R o-rwx "$install_dir" - #================================================= # REAPPLY SYSTEM CONFIGURATIONS #================================================= @@ -132,17 +132,20 @@ chown $app:$app "$install_dir/api/.env" ### ynh_replace_string --match_string="match_string" --replace_string="replace_string" --target_file="$install_dir/some_config_file" ### ynh_store_file_checksum --file="$install_dir/some_config_file" -#================================================= -# BUILD BACKEND -#================================================= -ynh_script_progression --message="Building crabfit backend..." --weight=10 -build_backend +if [ "$upgrade_type" == "UPGRADE_APP" ] +then + #================================================= + # BUILD BACKEND + #================================================= + ynh_script_progression --message="Building crabfit backend..." --weight=10 + build_backend -#================================================= -# BUILD FRONTEND -#================================================= -ynh_script_progression --message="Building crabfit frontend..." --weight=2 -build_frontend + #================================================= + # BUILD FRONTEND + #================================================= + ynh_script_progression --message="Building crabfit frontend..." --weight=2 + build_frontend +fi #================================================= # START SYSTEMD SERVICE