Compare commits

...

14 commits

Author SHA1 Message Date
Benjamin Bädorf af0effe5d3
Merge pull request 'Add banner to announce that some services are down' (#5) from axeman/pub.solar:add-down-banner into main
Some checks failed
continuous-integration/drone/push Build is failing
Reviewed-on: https://git.b12f.io/pub-solar/pub.solar/pulls/5
2023-01-07 19:05:34 +00:00
Akshay Mankar 68fd37a3fa Add banner to announce that some services are down 2023-01-07 19:44:39 +01:00
Benjamin Bädorf 516b6567a2
Fix mobile view, add copy button for code blocks 2022-12-10 16:55:06 +01:00
Benjamin Bädorf bee867764b
Merge pull request 'update/privacy-policy-22' (#4) from update/privacy-policy-22 into main
Reviewed-on: https://git.b12f.io/pub-solar/pub.solar/pulls/4
2022-12-09 13:12:17 +00:00
Benjamin Bädorf b9a9b15419
Merge branch 'main' into update/privacy-policy-22 2022-12-09 13:11:28 +00:00
Benjamin Bädorf ae78ddac73
Add PGP key 2022-11-29 00:36:26 +01:00
Benjamin Bädorf fb74ae600b
Add PGP fingerprint 2022-11-29 00:33:48 +01:00
Benjamin Bädorf e72baf3007
Randomize names 2022-11-28 19:51:55 +01:00
Benjamin Bädorf 0b51f722cf
Use pub.solar ID instead of account 2022-11-28 00:32:02 +01:00
Benjamin Bädorf 8e89c56cc9
Add link to auth page 2022-11-27 16:27:15 +01:00
Benjamin Bädorf 4b5bd3310d
Add link to keycloak account management 2022-11-27 16:24:00 +01:00
Benjamin Bädorf 06c8301698
Explicitly mention keycloak 2022-11-26 01:51:38 +01:00
Benjamin Bädorf 414be1506e
Update the english version of the privacy policy
This adds several sections. One makes it clear which stuff we will *not*
do with data. Then there is one section added per service, describing
the dataset collected when using this service, specifically.
2022-11-26 00:15:43 +01:00
Benjamin Bädorf 8a98d28812
Initial changes to privacy policy 2022-11-25 22:28:06 +01:00
11 changed files with 210 additions and 124 deletions

View file

@ -21,7 +21,7 @@ export default ({
theme={theme} theme={theme}
extraStylesheets={extraStylesheets} extraStylesheets={extraStylesheets}
cacheBust={cacheBust} cacheBust={cacheBust}
extraScripts={extraScripts} extraScripts={[...(extraScripts || []), '/scripts/copy-code.js']}
/> />
<body className="ps-main"> <body className="ps-main">

View file

@ -24,6 +24,11 @@ export default ({
<body className="ps-main"> <body className="ps-main">
<Background /> <Background />
<main className="ps-main--page ps-page ps-page_home"> <main className="ps-main--page ps-page ps-page_home">
<section className="ps-page--banner">
<div className="ps-page--banner-contents">
A few of our services are currently down due to an incident in one of our datacenters. We hope to bring them back up soon.
</div>
</section>
{links.map(({ href, title, openInNewTab }) => {links.map(({ href, title, openInNewTab }) =>
<a <a
href={href} href={href}

View file

@ -0,0 +1,16 @@
.ps-copy-code-button {
margin: 0;
background-color: var(--background-alt);
color: var(--foreground-alt);
text-transform: uppercase;
font-size: 12px;
border-radius: 1em;
margin-left: 0.25em;
border: 2px solid var(--foreground);
cursor: pointer;
&:hover {
background-color: var(--foreground);
color: var(--background);
}
}

View file

@ -21,10 +21,39 @@
flex-wrap: wrap; flex-wrap: wrap;
} }
&--banner {
border: 12px solid black;
width: 100%;
margin-left: 2vw;
margin-right: 2vw;
background: white;
word-break: break-word;
}
&--banner-contents {
color: var(--foreground);
background: white;
text-decoration: none;
text-align: center;
font-weight: 500;
font-size: 8rem;
line-height: 1em;
padding: 0.2vw;
margin: 2vw;
@media screen and (min-width: 700px) {
font-size: 4rem;
}
@media screen and (min-width: 1000px) {
font-size: 2rem;
}
}
&--section { &--section {
border: 12px solid black; border: 12px solid black;
margin-top: 10vh; margin-top: 10vh;
margin-bottom: 10vh; margin-bottom: 10vh;
width: 100%;
max-width: 700px; max-width: 700px;
flex-basis: 100%; flex-basis: 100%;
font-size: 16px; font-size: 16px;
@ -33,6 +62,8 @@
color: var(--foreground); color: var(--foreground);
background: white; background: white;
word-break: break-word; word-break: break-word;
display: flex;
flex-direction: column;
@media screen and (min-width: 1200px) { @media screen and (min-width: 1200px) {
margin: 1vw; margin: 1vw;
@ -97,6 +128,15 @@
padding: 4px; padding: 4px;
} }
pre {
display: flex;
flex-direction: row;
}
code {
overflow: scroll;
}
> * { > * {
margin-bottom: 0; margin-bottom: 0;
margin-top: 8px; margin-top: 8px;

View file

@ -29,5 +29,6 @@ html {
@import './background'; @import './background';
@import './footer'; @import './footer';
@import './homelink'; @import './homelink';
@import './copy-code-button.scss';
@import './hakken-dates.scss'; @import './hakken-dates.scss';

View file

@ -19,6 +19,12 @@ content:
You can reach us via [#General in Matrix](https://matrix.to/#/#general:pub.solar?via=chat.pub.solar) and [@crew on Mastodon](https://mastodon.pub.solar/@crew), or send a mail to [crew@pub.solar](mailto:crew@pub.solar). You can reach us via [#General in Matrix](https://matrix.to/#/#general:pub.solar?via=chat.pub.solar) and [@crew on Mastodon](https://mastodon.pub.solar/@crew), or send a mail to [crew@pub.solar](mailto:crew@pub.solar).
You can find our PGP key [here](https://keys.openpgp.org/vks/v1/by-fingerprint/8A8987ADE3736C8CA2EB315A9B809EBBDD62BAE3). It has the following fingerprint:
```
8A89 87AD E373 6C8C A2EB 315A 9B80 9EBB DD62 BAE3
```
## Being a member or helping hand ## Being a member or helping hand
Are you interested in becoming a member of the pub.solar organisation? Do you want to support the organisation with labour, money, or just your name? Are you interested in becoming a member of the pub.solar organisation? Do you want to support the organisation with labour, money, or just your name?
@ -32,7 +38,15 @@ content:
## Imprint ## Imprint
pub.solar n.e.V. pub.solar n.e.V.
Benjamin Bädorf, Jhonas Wernery, Hendrik Sokolowki <script>
document.write(
'<p>' +
(['Benjamin Bädorf', 'Jhonas Wernery', 'Hendrik Sokolowki']
.sort(() => Math.random() - 0.5)
.join(', ')) +
'</p>'
);
</script>
c/o MiOM 202, c/o MiOM 202,
Wilhelm-Mauser-Straße 47 Halle 5, Wilhelm-Mauser-Straße 47 Halle 5,
D-50827 Köln, D-50827 Köln,
@ -67,6 +81,12 @@ content:
Du kannst uns via [#General in Matrix](https://matrix.to/#/#general:pub.solar?via=chat.pub.solar) und [@crew auf Mastodon](https://mastodon.pub.solar/@crew) erreichen, oder eine Mail an [crew@pub.solar](mailto:crew@pub.solar) schicken. Du kannst uns via [#General in Matrix](https://matrix.to/#/#general:pub.solar?via=chat.pub.solar) und [@crew auf Mastodon](https://mastodon.pub.solar/@crew) erreichen, oder eine Mail an [crew@pub.solar](mailto:crew@pub.solar) schicken.
Unseren PGP Schlüssel findest du [hier](https://keys.openpgp.org/vks/v1/by-fingerprint/8A8987ADE3736C8CA2EB315A9B809EBBDD62BAE3). Er hat folgenden Fingerabdruck:
```
8A89 87AD E373 6C8C A2EB 315A 9B80 9EBB DD62 BAE3
```
## Mitglied oder Helfer*in werden ## Mitglied oder Helfer*in werden
Bist du daran interessiert ein Mitglied von pub.solar n.e.V. zu werden? Du würdest die Organisation gerne mit Arbeit, Geld, oder einfach nur deinen Namen unterstützen? Bist du daran interessiert ein Mitglied von pub.solar n.e.V. zu werden? Du würdest die Organisation gerne mit Arbeit, Geld, oder einfach nur deinen Namen unterstützen?
@ -80,7 +100,15 @@ content:
## Impressum ## Impressum
pub.solar n.e.V. pub.solar n.e.V.
Benjamin Bädorf, Jhonas Wernery, Hendrik Sokolowki <script>
document.write(
'<p>' +
(['Benjamin Bädorf', 'Jhonas Wernery', 'Hendrik Sokolowki']
.sort(() => Math.random() - 0.5)
.join(', ')) +
'</p>'
);
</script>
c/o MiOM 202, c/o MiOM 202,
Wilhelm-Mauser-Straße 47 Halle 5, Wilhelm-Mauser-Straße 47 Halle 5,
D-50827 Köln, D-50827 Köln,

View file

@ -1,7 +1,7 @@
import MarkdownIt from "https://jspm.dev/markdown-it"; import MarkdownIt from "https://jspm.dev/markdown-it";
const mdIt = new MarkdownIt({ const mdIt = new MarkdownIt({
html: false, // Enable HTML tags in source html: true, // Enable HTML tags in source
xhtmlOut: false, // Use '/' to close single tags (<br />). xhtmlOut: false, // Use '/' to close single tags (<br />).
// This is only for full CommonMark compatibility. // This is only for full CommonMark compatibility.
breaks: true, // Convert '\n' in paragraphs into <br> breaks: true, // Convert '\n' in paragraphs into <br>

View file

@ -1,109 +0,0 @@
(() => {
const skippedMonths = [
{ m: 8, y: 2022 },
{ m: 12, y: 2022 },
];
const i18n = {
en: {
comingDates: 'The following dates are scheduled:',
friday: 'friday',
sunday: 'sunday',
until: 'until',
months: [
'Jan.',
'Feb.',
'Mar.',
'Apr.',
'May',
'Jun.',
'Jul.',
'Aug.',
'Sep.',
'Oct.',
'Nov.',
'Dec.',
],
},
de: {
comingDates: 'Folgende Termine stehen an:',
friday: 'Freitag',
sunday: 'Sonntag',
until: 'bis',
months: [
'Jan.',
'Feb.',
'Mär.',
'Apr.',
'Mai',
'Jun.',
'Jul.',
'Aug.',
'Sep.',
'Okt.',
'Nov.',
'Dez.',
],
},
};
const datesLists = {
en: document.getElementById('dates-list-en'),
de: document.getElementById('dates-list-de'),
};
const day = 24 * 60 * 60 * 1000;
const week = 7 * day;
const endOfWeekend = 2 * day;
const start = new Date();
const hakkens = [];
// We'll be looking about half a year into the future
for (let i = 0; i < 185; i++) {
const dateToTry = new Date(start.valueOf() + (i * day));
if (dateToTry.getDay() !== 5) {
continue;
}
const oneWeekLater = new Date(dateToTry.valueOf() + week);
if (dateToTry.getMonth() === oneWeekLater.getMonth()) {
continue;
}
const m = dateToTry.getMonth() + 1;
const y = dateToTry.getFullYear();
if (skippedMonths.find((s) => s.m === m && s.y === y)) {
continue;
}
hakkens.push(dateToTry);
}
// Helper function to add leading zeros to dates
const d = (num) => ('0' + num).slice(-2);
const writeText = (lang) => {
const p = document.createElement('p');
p.innerHTML = i18n[lang].comingDates;
datesLists[lang].appendChild(p);
}
const writeDateList = (lang) => {
const ul = document.createElement('ul');
hakkens.forEach(hakken => {
hakkend = new Date(hakken.valueOf() + endOfWeekend);
const showFirstMonth = hakken.getMonth() !== hakkend.getMonth();
const li = document.createElement('li');
li.innerHTML = `
${i18n[lang].friday} ${d(hakken.getDate())}. ${showFirstMonth ? i18n[lang].months[hakken.getMonth()] : ''}
${i18n[lang].until}
${d(hakkend.getDate())}. ${i18n[lang].months[hakkend.getMonth()]}
`;
ul.appendChild(li);
});
datesLists[lang].appendChild(ul);
}
writeText('de');
writeText('en');
writeDateList('de');
writeDateList('en');
})();

View file

@ -4,6 +4,8 @@ links:
- href: https://en.wikipedia.org/wiki/Free_software - href: https://en.wikipedia.org/wiki/Free_software
title: Fucking Free title: Fucking Free
openInNewTab: true openInNewTab: true
- href: https://auth.pub.solar/realms/pub.solar/account
title: Your pub.solar ID
- href: https://cloud.pub.solar/ - href: https://cloud.pub.solar/
title: Nextcloud title: Nextcloud
openInNewTab: true openInNewTab: true

View file

@ -6,9 +6,17 @@ content:
en: | en: |
# Privacy Policy # Privacy Policy
Information on data privacy and protection for the Matrix service operated by pub.solar n.e.V. as required by article 13 DSGVO Information on data privacy and protection for the services operated by pub.solar n.e.V. as required by article 13 DSGVO.
**Explanation**: Our Matrix service consists of the "Homeserver"; `https://matrix.pub.solar`, as well as the web-based Element-Messenger ([chat.pub.solar](https://chat.pub.solar/)). ## Services
We run multiple public services:
* our Matrix service, consisting of the "Homeserver"; `https://matrix.pub.solar`, as well as the web-based Element-Messenger ([chat.pub.solar](https://chat.pub.solar/)),
* our Nextcloud service at `https://cloud.pub.solar`,
* our Mastodon service at `https://mastodon.pub.solar`.
* our Gitea service at `https://git.pub.solar`.
* our Keycloak authentication service at `https://auth.pub.solar`.
## Responsible for operating the service ## Responsible for operating the service
@ -29,15 +37,17 @@ content:
## What personal data is processed? ## What personal data is processed?
The processing includes the following personal data: If a user chooses to use any of the services provided by us, the following data will be required and therefore collected by pub.solar in the authentication service:
* Access control: matrix ID, display name, e-mail address (optional), phone number (optional) A valid email address: required for account creation. This email address is deleted from our database after the account has been approved/denied, unless the user chooses during the registration process, to keep it for password reset process.
* Authentication: username and password
* User content: all data that the user enters into the system (end-to-end encryption is enabled by default in 1:1 rooms) An username and a password: required to identify the account holder and provide the services offered by pub.solar.
* Device identification: IP addresses with time stamp and device name; type of end device used (mobile / desktop), operating system
* Server log: IP addresses with timestamp Necessary information related to the operation and functioning of the services which may include, for example, IP address, User Agent, etc. More detailed information about this and how we handle it can be found in the Privacy notices per service.
* Audio/video chat: IP addresses, audio/video data
* Notifications (e-mail) When a user makes an online donation to pub.solar, we collect personal data such as, but not limited to, username (if any), country (in case of extra storage request for tax purposes), transaction IDs or bank account/reference. The purpose for which we use this data is merely administrative (verification of regular donations, accounting management) and is maintained under the same security measures described in the "How do we store your data?" section. Since all the data we collect is previously processed by a third-party payment processor such as PayPal, Patreon or Liberapay, by using these or similar services, their use of your information is based on their terms of service and policies, not ours, so we encourage you to review those policies carefully.
Any additional information that the user chooses to supply while using the services provided by us (whether it is chats, posts, emails, etc.). This additional information is optional and with the user's consent.
## How long will the personal data be stored? ## How long will the personal data be stored?
@ -45,7 +55,7 @@ content:
## Where is the personal data stored? ## Where is the personal data stored?
We run our Matrix service on servers of the company [Greenbaum Cloud](https://greenbaum.cloud/). We run our all of our services on servers of the company [Greenbaum Cloud](https://greenbaum.cloud/).
## Data subject rights ## Data subject rights
@ -60,6 +70,62 @@ content:
* right to data portability, * right to data portability,
* right to lodge a complaint with a data protection supervisory authority if you believe that we are not processing your data properly. The State Commissioner for Data Protection and Freedom of Information in Nordrhein-Westfalen is responsible in our case. However, if you are in another federal state or not in Germany, you can also contact the data protection authority there. * right to lodge a complaint with a data protection supervisory authority if you believe that we are not processing your data properly. The State Commissioner for Data Protection and Freedom of Information in Nordrhein-Westfalen is responsible in our case. However, if you are in another federal state or not in Germany, you can also contact the data protection authority there.
## What we do not do with your data
We do not collect any other data than what is needed to provide you the service.
We do not, in any way, process, analyze your behavior or personal characteristics to create profiles about you or your usage of the services. We have no advertisements or business relationships with advertisers.
We do not sell your data to any third party.
We do not share your data to any third party unless in case of federated services which requires certain data to be shared in order to operate (e.g. other email service provider needs to know your email address to be able to deliver emails).
We do not require any additional information that is not crucial for the operation of the service (we do not ask for phone numbers, private personal data, home address).
We do not read/look nor process your personal data, emails, files, etc., stored on our servers unless needed for providing the service, troubleshooting purposes or under suspicion of breaking our Terms Of Services in which case we ask for prior permission from you or inform you afterwards of all actions taken against the account in the transparency report addressed to account holder.
## Privacy Policy per service
### Cloud
Our cloud runs Nextcloud.
This service requires login with pub.solar credentials.
Everything (files, calendars, contacts, news, tasks, bookmarks, etc.) is stored unencrypted in a database, unless an application provides external encryption (none so far). This is a limitation of the software we are utilizing for this service (Nextcloud).
We do not currently encrypt files when you upload them because we've had some bad experiences with dataloss incurred through end-to-end encryption.
Server logs, which store information such as, but not limited to, your IP address, your username, an app currently used, error messages and User Agent, are stored for a period of 24 hours after which they are deleted from the server. No backup of log files is created. Logs are kept to prevent brute-force attacks on accounts and to provide quick insight when debugging issues.
### Git
This service requires login with pub.solar credentials.
Server logs, which store information such as, but not limited to, your IP address, your username, error messages and User Agent, are stored for a period of 24 hours after which they are deleted from the server. No backup of log files is created. Logs are kept to prevent brute-force attacks on accounts and to provide quick insight when debugging issues.
All git data such as, but not limited to, usernames, email addresses, messages, code, files, versions, pull requests, etc., are stored on the server in the database as is (plain-text).
### Matrix
This service requires login with pub.solar credentials.
Server logs, which store information such as, but not limited to, your IP address, your username, error messages and User Agent, are stored for a period of 24 hours after which they are deleted from the server. No backup of log files is created. Logs are kept to prevent brute-force attacks on accounts and to provide quick insight when debugging issues.
All git data such as, but not limited to, usernames, email addresses, messages, code, files, versions, pull requests, etc., are stored on the server in the database as is (plain-text).
### Mastodon
This service requires login with pub.solar credentials.
Basic account information: If you register on this server, you may be asked to enter a username, an e-mail address and a password. You may also enter additional profile information such as a display name and biography, and upload a profile picture and header image. The username, display name, biography, profile picture and header image are always listed publicly.
Posts, following and other public information: The list of people you follow is listed publicly, the same is true for your followers. When you submit a message, the date and time is stored as well as the application you submitted the message from. Messages may contain media attachments, such as pictures and videos. Public and unlisted posts are available publicly. When you feature a post on your profile, that is also publicly available information. Your posts are delivered to your followers, in some cases it means they are delivered to different servers and copies are stored there. When you delete posts, this is likewise delivered to your followers. The action of reblogging or favouriting another post is always public.
Direct and followers-only posts: All posts are stored and processed on the server. Followers-only posts are delivered to your followers and users who are mentioned in them, and direct posts are delivered only to users mentioned in them. In some cases it means they are delivered to different servers and copies are stored there. We make a good faith effort to limit the access to those posts only to authorized persons, but other servers may fail to do so. Therefore it's important to review servers your followers belong to. You may toggle an option to approve and reject new followers manually in the settings. Please keep in mind that the operators of the server and any receiving server may view such messages, and that recipients may screenshot, copy or otherwise re-share them. Do not share any sensitive information over Mastodon.
IPs and other metadata: When you log in, we record the IP address you log in from, as well as the name of your browser application. All the logged in sessions are available for your review and revocation in the settings. The latest IP address used is stored for up to 12 months. We also may retain server logs which include the IP address of every request to our server.
## References/License ## References/License
We have created the basic structure of this data protection information with the help of [DS-GVO.clever-Tools](https://www.baden-wuerttemberg.datenschutz.de/ds-gvo.clever/) and adapted it to our needs. We have also used parts of [Datenschutzerklärung der TU-Dresden](https://doc.matrix.tu-dresden.de/privacy/) and adjusted them accordingly. Text is licensed [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.de). We have created the basic structure of this data protection information with the help of [DS-GVO.clever-Tools](https://www.baden-wuerttemberg.datenschutz.de/ds-gvo.clever/) and adapted it to our needs. We have also used parts of [Datenschutzerklärung der TU-Dresden](https://doc.matrix.tu-dresden.de/privacy/) and adjusted them accordingly. Text is licensed [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.de).

37
scripts/copy-code.js Normal file
View file

@ -0,0 +1,37 @@
(() => {
const findLanguage = (el) => {
if (el.lang) {
return el.lang;
}
if (el.parentElement) {
return findLanguage(el.parentElement);
}
return 'en';
}
const codeInPreElements = document.querySelectorAll('section pre code');
codeInPreElements.forEach((element) => {
const lang = findLanguage(element);
const button = document.createElement('button');
const resetButtonText = () => {
button.innerHTML = { en: 'Copy', de: 'Kopieren' }[lang];
}
button.className = 'ps-copy-code-button';
button.addEventListener('click', () => {
navigator.clipboard.writeText(element.innerHTML);
button.innerHTML = { en: 'Copied!', de: 'Kopiert!' }[lang];
setTimeout(resetButtonText, 1000);
});
resetButtonText();
element.after(button);
});
})();