Some maintenance things + secure auth cookies #16

Closed
Ghost wants to merge 7 commits from (deleted):thing into develop
15 changed files with 84 additions and 160 deletions

2
.gitignore vendored
View file

@ -20,3 +20,5 @@ selenium-debug.log
package-lock.json
coverage/
dist.zip

View file

@ -1,97 +0,0 @@
image: node:10-alpine
variables: &global_variables
DOCKER_DRIVER: overlay2
DOCKER_HOST: unix:///var/run/docker.sock
cache: &global_cache_policy
key: '$CI_COMMIT_SHORT_SHA'
policy: pull-push
paths:
- node_modules/
- build
stages:
- build
- test
- release
build:
stage: build
before_script: &before-build
- apk --no-cache add git
script:
- npm install
- npm run build:prod
artifacts: &release-artifacts
name: "admin-fe-$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA"
paths:
- dist/
lint:
stage: test
before_script: &before-yarn
- apk --no-cache add git
- yarn cache clean
- yarn
cache:
key: '$CI_COMMIT_SHORT_SHA'
policy: pull
script:
- yarn lint
test:
stage: test
before_script: *before-yarn
cache:
key: '$CI_COMMIT_SHORT_SHA'
policy: pull
script:
- yarn test
docker:
stage: release
image: docker:latest
cache: {}
dependencies: []
variables: &docker-variables
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
IMAGE_TAG_SLUG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
IMAGE_TAG_LATEST: $CI_REGISTRY_IMAGE:latest
IMAGE_TAG_LATEST_STABLE: $CI_REGISTRY_IMAGE:stable
before_script: &before-docker
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker pull $IMAGE_TAG_SLUG || true
- export CI_JOB_TIMESTAMP=$(date --utc -Iseconds)
- export CI_VCS_REF=$CI_COMMIT_SHORT_SHA
allow_failure: true
script:
- docker build --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG -t $IMAGE_TAG_LATEST .
- docker push $IMAGE_TAG
- docker push $IMAGE_TAG_SLUG
- docker push $IMAGE_TAG_LATEST
tags:
- dind
only:
- develop@pleroma/admin-fe
- /^(features|ci)\/.*/@jp/admin-fe
docker-stable:
stage: release
image: docker:latest
cache: {}
dependencies: []
variables: *docker-variables
before_script: *before-docker
allow_failure: true
script:
- docker build --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG -t $IMAGE_TAG_LATEST_STABLE .
- docker push $IMAGE_TAG
- docker push $IMAGE_TAG_SLUG
- docker push $IMAGE_TAG_LATEST_STABLE
tags:
- dind
only:
- master@pleroma/admin-fe

View file

@ -1,5 +0,0 @@
language: node_js
node_js: stable
script: npm run test
notifications:
email: false

24
CODE_OF_CONDUCT.md Normal file
View file

@ -0,0 +1,24 @@
# Akkoma Code of Conduct
The Akkoma project aims to be **enjoyable** for anyone to participate in, regardless of their identity or level of expertise. To achieve this, the community must create an environment which is **safe** and **equitable**; the following guidelines have been created with these goals in mind.
1. **Treat individuals with respect.** Differing experiences and viewpoints deserve to be respected, and bigotry and harassment are not tolerated under any circumstances.
- Individuals should at all times be treated as equals, regardless of their age, gender, sexuality, race, ethnicity, _or any other characteristic_, intrinsic or otherwise.
- Behaviour that is harmful in nature should be addressed and corrected *regardless of intent*.
- Respect personal boundaries and ask for clarification whenever they are unclear.
- (Obviously, hate does not count as merely a "differing viewpoint", because it is harmful in nature.)
2. **Be understanding of differences in communication.** Not everyone is aware of unspoken social cues, and speech that is not intended to be offensive should not be treated as such simply due to an atypical manner of communication.
- Somebody who speaks bluntly is not necessarily rude, and somebody who swears a lot is not necessarily volatile.
- Try to confirm your interpretation of their intent rather than assuming bad faith.
- Someone may not communicate as, or come across as a picture of "professionalism", but this should not be seen as a reason to dismiss them. This is a **casual** space, and communication styles can reflect that.
3. **"Uncomfortable" does not mean "unsafe".** In an ideal world, the community would be safe, equitable, enjoyable, *and* comfortable for all members at all times. Unfortunately, this is not always possible in reality.
- Safety and equity will be prioritized over comfort whenever it is necessary to do so.
- Weaponizing one's own discomfort to deflect accountability or censor an individual (e.g. "white fragility") is a form of discriminatory conduct.
4. **Let people grow from their mistakes.** Nobody is perfect; even the most well-meaning individual can do something hurtful. Everyone should be given a fair opportunity to explain themselves and correct their behaviour. Portraying someone as inherently malicious prevents improvement and shifts focus away from the *action* that was problematic.
- Avoid bringing up past events that do not accurately reflect an individual's current actions or beliefs. (This is, of course, different from providing evidence of a recurring pattern of behaviour.)
---
This document was adapted from one created by ~keith as part of punks default repository template, and is licensed under CC-BY-SA 4.0. The original template is here: <https://bytes.keithhacks.cyou/keith/default-template>

View file

@ -8,14 +8,14 @@ RUN apk --no-cache add git && \
FROM nginx:mainline-alpine
LABEL maintainer="ops@pleroma.social" \
org.opencontainers.image.title="pleroma-adminfe" \
org.opencontainers.image.description="Pleroma-adminfe for Docker" \
org.opencontainers.image.authors="ops@pleroma.social" \
org.opencontainers.image.vendor="pleroma.social" \
org.opencontainers.image.documentation="https://git.pleroma.social/pleroma/pleroma-adminfe" \
LABEL maintainer="hannah@coffee-and-dreams.uk" \
org.opencontainers.image.title="akkoma-adminfe" \
org.opencontainers.image.description="Akkoma-adminfe for Docker" \
org.opencontainers.image.authors="hannah@coffee-and-dreams.uk" \
org.opencontainers.image.vendor="akkoma.dev" \
org.opencontainers.image.documentation="https://akkoma.dev/AkkomaGang/admin-fe" \
org.opencontainers.image.licenses="AGPL-3.0" \
org.opencontainers.image.url="https://pleroma.social" \
org.opencontainers.image.url="https://akkoma.dev" \
org.opencontainers.image.revision=$VCS_REF \
org.opencontainers.image.created=$BUILD_DATE

View file

@ -1,10 +1,10 @@
# Pleroma AdminFE
# Akkoma AdminFE
![screenshot](./public/index.png)
## About
Admin UI for pleroma instance owners.
Admin UI for Akkoma instance owners.
### Branches
@ -18,7 +18,7 @@ There are two main branches here:
1. User administration: grant roles to users (admin/moderator), deactivate/delete as well as force their statuses to have NSFW tag, strip media and many more
1. Invites management: generate invite tokens & send invites via email
1. Moderation log: track moderator/admin actions
1. Settings: configure your pleroma instance via friendly (hopefully) UI
1. Settings: configure your Akkoma instance via friendly (hopefully) UI
1. Emoji packs: configure your emoji packs
You can have any combination of these features (i.e. you can disable anything, but user administration, see "Disabling features" section below).
@ -27,7 +27,7 @@ You can have any combination of these features (i.e. you can disable anything, b
### Bundled
AdminFE is bundled with Pleroma, i.e. you can just visit `https://your.instance/pleroma/admin/` to try it out.
AdminFE is bundled with Akkoma, i.e. you can just visit `https://your.instance/pleroma/admin/` to try it out.
### Development
@ -87,6 +87,6 @@ Modern browsers and Internet Explorer 10+.
## License
Pleroma AdminFE is build on top of the [Vue Element Admin](https://github.com/PanJiaChen/vue-element-admin), which is licensed under [MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE) license.
Akkoma AdminFE is build on top of the [Vue Element Admin](https://github.com/PanJiaChen/vue-element-admin), which is licensed under [MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE) license.
AdminFE's own code is licensed under [AGPL](./AGPL-3)

View file

@ -19,7 +19,7 @@ http {
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
proxy_cache_path /tmp/pleroma-media-cache levels=1:2 keys_zone=pleroma_media_cache:10m max_size=10g
proxy_cache_path /tmp/akkoma-media-cache levels=1:2 keys_zone=akkoma_media_cache:10m max_size=10g
inactive=720m use_temp_path=off;
server {
listen 80;

View file

@ -5,9 +5,9 @@
"author": "Pan <panfree23@gmail.com>",
"license": "MIT",
"scripts": {
"dev": "cross-env BABEL_ENV=development webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js",
"build:sit": "cross-env NODE_ENV=production env_config=sit node build/build.js",
"dev": "cross-env NODE_OPTIONS=--openssl-legacy-provider BABEL_ENV=development webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"build:prod": "cross-env NODE_OPTIONS=--openssl-legacy-provider NODE_ENV=production env_config=prod node build/build.js",
"build:sit": "cross-env NODE_OPTIONS=--openssl-legacy-provider NODE_ENV=production env_config=sit node build/build.js",
"lint": "eslint --ext .js,.vue src",
"test": "jest",
"test:debug": "node --inspect-brk node_modules/.bin/jest --runInBand",

View file

@ -93,15 +93,15 @@ export default {
login: {
title: 'Login Form',
logIn: 'Log in',
logInViaPleromaFE: 'Log in via PleromaFE',
logInViaAkkomaFE: 'Log in via AkkomaFE',
username: 'username@host',
password: 'password',
omitHostname: 'Omit hostname if Pleroma is located on this domain',
errorMessage: 'Username must contain username and host, e.g. john@pleroma.social',
omitHostname: 'Omit hostname if Akkoma is located on this domain',
errorMessage: 'Username must contain username and host, e.g. user@instance.tld',
any: 'any',
thirdparty: 'Or connect with',
pleromaFELoginFailed: 'Failed to login via PleromaFE, please login with username/password',
pleromaFELoginSucceed: 'Logged in via PleromaFE'
akkomaFELoginFailed: 'Failed to login via AkkomaFE, please login with username/password',
akkomaFELoginSucceed: 'Logged in via AkkomaFE'
},
mediaProxyCache: {
mediaProxyCache: 'MediaProxy Cache',

View file

@ -1,15 +1,15 @@
import localforage from 'localforage'
import _ from 'lodash'
const pleromaFEStateKey = 'vuex-lz'
const akkomaFEStateKey = 'vuex-lz'
export const authenticateWithPleromaFE = async(store) => {
const pleromaFEState = await localforage.getItem(pleromaFEStateKey)
const token = _.get(pleromaFEState, 'oauth.userToken')
export const authenticateWithAkkomaFE = async(store) => {
const akkomaFEState = await localforage.getItem(akkomaFEStateKey)
const token = _.get(akkomaFEState, 'oauth.userToken')
if (token === undefined) {
throw new Error('PleromaFE token not found')
throw new Error('AkkomaFE token not found')
}
await store.dispatch('LoginByPleromaFE', { token })
await store.dispatch('LoginByAkkomaFE', { token })
}

View file

@ -83,7 +83,7 @@ const user = {
getUserInfo(state.token, state.authHost).then(response => {
const data = response.data
const message = '<span>This user doesn\`t have admin rights. Try another credentials or see the </span>' +
'<u><a target="_blank" href="https://docs.pleroma.social/backend/administration/CLI_tasks/user/#set-the-value-of-the-given-users-settings">docs</a></u>' +
'<u><a target="_blank" href="https://docs.akkoma.dev/stable/administration/CLI_tasks/user/#set-the-value-of-the-given-users-settings">docs</a></u>' +
'<span> to find out how to make this user an admin</span>'
if (!data) {
@ -120,7 +120,7 @@ const user = {
resolve()
})
},
async LoginByPleromaFE({ commit, dispatch }, { token }) {
async LoginByAkkomaFE({ commit, dispatch }, { token }) {
commit('SET_TOKEN', token)
setToken(token)
commit('SET_AUTH_HOST', window.location.host)

View file

@ -1,14 +1,14 @@
import Cookies from 'js-cookie'
const TokenKey = 'Admin-Token'
const AuthHostKey = 'Auth-Host'
const TokenKey = process.env.NODE_ENV === 'production' ? '__Host-Admin-Token' : 'Admin-Token'
const AuthHostKey = process.env.NODE_ENV === 'production' ? '__Host-Auth-Host' : 'Auth-Host'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
return process.env.NODE_ENV === 'production' ? Cookies.set(TokenKey, token, { secure: true, sameSite: 'strict' }) : Cookies.set(TokenKey, token)
}
export function removeToken() {
@ -20,7 +20,7 @@ export function getAuthHost() {
}
export function setAuthHost(token) {
return Cookies.set(AuthHostKey, token)
return process.env.NODE_ENV === 'production' ? Cookies.set(AuthHostKey, token, { secure: true, sameSite: 'strict' }) : Cookies.set(AuthHostKey, token)
}
export function removeAuthHost() {

View file

@ -41,9 +41,9 @@
<el-button :loading="loading" class="login-button" type="primary" @click.native.prevent="handleLogin">
{{ $t('login.logIn') }}
</el-button>
<!-- Note: PleromaFE login feature relies on admin scope presence in PleromaFE token (older versions of PleromaFE don't support it) -->
<el-button v-if="pleromaFEToken" :loading="loadingPleromaFE" class="login-button" type="primary" @click.native.prevent="handlePleromaFELogin">
{{ $t('login.logInViaPleromaFE') }}
<!-- Note: AkkomaFE login feature relies on admin scope presence in AkkomaFE token (older versions of AkkomaFE don't support it) -->
<el-button v-if="akkomaFEToken" :loading="loadingAkkomaFE" class="login-button" type="primary" @click.native.prevent="handleAkkomaFELogin">
{{ $t('login.logInViaAkkomaFE') }}
</el-button>
</el-form>
</div>
@ -54,7 +54,7 @@ import SvgIcon from '@/components/element-ui/SvgIcon'
import localforage from 'localforage'
import _ from 'lodash'
import i18n from '@/lang'
import { authenticateWithPleromaFE } from '@/services/pleromaAuth'
import { authenticateWithAkkomaFE } from '@/services/pleromaAuth'
export default {
name: 'Login',
@ -67,12 +67,12 @@ export default {
},
passwordType: 'password',
loading: false,
loadingPleromaFE: false,
loadingAkkomaFE: false,
showDialog: false,
redirect: undefined,
pleromaFEToken: false,
pleromaFEStateKey: 'vuex-lz',
pleromaFEState: {}
akkomaFEToken: false,
akkomaFEStateKey: 'vuex-lz',
akkomaFEState: {}
}
},
watch: {
@ -84,14 +84,14 @@ export default {
}
},
async mounted() {
const pleromaFEState = await localforage.getItem(this.pleromaFEStateKey)
this.pleromaFEState = pleromaFEState
const akkomaFEState = await localforage.getItem(this.akkomaFEStateKey)
this.akkomaFEState = akkomaFEState
if (_.get(pleromaFEState, 'oauth.userToken') === undefined) {
if (_.get(akkomaFEState, 'oauth.userToken') === undefined) {
return
}
this.pleromaFEToken = true
this.akkomaFEToken = true
},
methods: {
showPwd() {
@ -111,18 +111,18 @@ export default {
this.loading = false
})
},
async handlePleromaFELogin() {
this.loadingPleromaFE = true
async handleAkkomaFELogin() {
this.loadingAkkomaFE = true
try {
await authenticateWithPleromaFE(this.$store)
await authenticateWithAkkomaFE(this.$store)
} catch (error) {
this.loadingPleromaFE = false
this.$message.error(i18n.t('login.pleromaFELoginFailed'))
this.loadingAkkomaFE = false
this.$message.error(i18n.t('login.akkomaFELoginFailed'))
}
this.loadingPleromaFE = false
this.loadingAkkomaFE = false
this.$message.success(i18n.t('login.pleromaFELoginSucceed'))
this.$message.success(i18n.t('login.akkomaFELoginSucceed'))
this.$router.push({ path: this.redirect || '/users/index' })
},
getLoginData() {

View file

@ -4,23 +4,23 @@
<script>
import { Loading } from 'element-ui'
import { authenticateWithPleromaFE } from '@/services/pleromaAuth'
import { authenticateWithAkkomaFE } from '@/services/pleromaAuth'
import i18n from '@/lang'
export default {
name: 'LoginPleroma',
name: 'LoginAkkoma',
async mounted() {
const loadingInstance = Loading.service({ fullscreen: true })
try {
await authenticateWithPleromaFE(this.$store)
await authenticateWithAkkomaFE(this.$store)
} catch (error) {
this.$message.error(i18n.t('login.pleromaFELoginFailed'))
this.$message.error(i18n.t('login.akkomaFELoginFailed'))
}
loadingInstance.close()
this.$router.push({ path: '/users/index' })
this.$message.success(i18n.t('login.pleromaFELoginSucceed'))
this.$message.success(i18n.t('login.akkomaFELoginSucceed'))
}
}
</script>

View file

@ -36,7 +36,7 @@
<h1 class="settings-header">{{ $t('settings.settings') }}</h1>
<el-link
:underline="false"
href="https://docs-develop.pleroma.social/backend/administration/CLI_tasks/config/"
href="https://docs.akkoma.dev/stable/administration/CLI_tasks/config/"
target="_blank">
<el-button class="settings-docs-button">
<span>