Skip to content

Commit

Permalink
Merge pull request #169 from leaonline/release-ios
Browse files Browse the repository at this point in the history
Release 1.1.0 (Android)
  • Loading branch information
jankapunkt committed Oct 25, 2023
2 parents 70e3c56 + d0a2ce9 commit d2c50e7
Show file tree
Hide file tree
Showing 752 changed files with 56,163 additions and 33,340 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/backend.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Backend Test suite
name: Backend Tests

on:
push:
Expand All @@ -8,7 +8,7 @@ on:

jobs:
lintcode:
name: Javascript lint
name: Backend JS lint
runs-on: ubuntu-latest
steps:
- name: checkout
Expand All @@ -31,7 +31,7 @@ jobs:
- run: cd backend && npm run lint:code

tests:
name: Meteor ${{ matrix.meteor }} tests
name: Backend Meteor ${{ matrix.meteor }} tests
runs-on: ubuntu-latest
steps:
- name: checkout
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/jest_test.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
name: Jest Test
name: App Tests


on:
push:
branches:
- main

pull_request:


jobs:
build:
runs-on: ubuntu-latest
Expand All @@ -29,7 +27,7 @@ jobs:
${{ runner.os }}-node-
- name: install node modules
run: cd src && npm ci
run: cd src && npm i --legacy-peer-deps --force

- name: run jest tests
run: cd src && npm test
4 changes: 2 additions & 2 deletions .github/workflows/jsdoc_test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: JSDOC Test
name: App Build Docs

on:
push:
Expand Down Expand Up @@ -26,6 +26,6 @@ jobs:
${{ runner.os }}-node-
- name: install node modules
run: cd src && npm ci
run: cd src && npm i --legacy-peer-deps --force
- name: run jsdoc
run: cd src && npm run docs
4 changes: 2 additions & 2 deletions .github/workflows/lint_test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Lint Test
name: App JS Lint

on:
push:
Expand Down Expand Up @@ -26,6 +26,6 @@ jobs:
${{ runner.os }}-node-
- name: install node modules
run: cd src && npm ci
run: cd src && npm i --legacy-peer-deps --force
- name: run standard js
run: cd src && npm run lint
7 changes: 2 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# lea.online App

[![Build Android APK](https://github.com/leaonline/leaonline-app/actions/workflows/build_android_apk.yml/badge.svg)](https://github.com/leaonline/leaonline-app/actions/workflows/build_android_apk.yml)
[![Test suite](https://github.com/leaonline/leaonline-app/actions/workflows/jest_test.yml/badge.svg)](https://github.com/leaonline/leaonline-app/actions/workflows/jest_test.yml)
[![Lint Test](https://github.com/leaonline/leaonline-app/actions/workflows/lint_test.yml/badge.svg)](https://github.com/leaonline/leaonline-app/actions/workflows/lint_test.yml)
[![Project Status: WIP – Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](https://www.repostatus.org/badges/latest/wip.svg)](https://www.repostatus.org/#wip)
Expand All @@ -13,8 +12,8 @@ The lea.online app is a mobile app, developed using React-Native and Meteor.

## Get the app

[We have released the Android app](https://play.google.com/store/apps/details?id=com.testCompany.leaonline)
We are working on the iOS release!
- Android: https://play.google.com/store/apps/details?id=com.testCompany.leaonline
- IOS: Coming soon


## Development
Expand All @@ -40,5 +39,3 @@ development.
## License

This work is published unter AGPL-3.0 as stated in the [license file](./LICENSE).


1 change: 1 addition & 0 deletions backend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public/fonts/
public/logos/

.deploy
.staging

# Logs
logs
Expand Down
2 changes: 1 addition & 1 deletion backend/.meteor/versions
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ leaonline:collection-factory@1.0.4
leaonline:corelib@1.0.0
leaonline:ddp-login@2.0.2
leaonline:ddp-login-handler@2.0.0
leaonline:method-factory@1.1.0
leaonline:method-factory@1.1.1
leaonline:publication-factory@1.1.1
leaonline:ratelimit-factory@1.0.0
leaonline:service-registry@1.0.0
Expand Down
3 changes: 2 additions & 1 deletion backend/.settingsschema.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ const schema = def => new SimpleSchema(def)

const settingsSchema = schema({
app: schema({
name: String
name: String,
token: String
}),
isStaging: Boolean,
defaultLang: String,
Expand Down
55 changes: 0 additions & 55 deletions backend/api/accounts/UserEmail.js

This file was deleted.

10 changes: 10 additions & 0 deletions backend/api/accounts/isBackendUser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { hasProp } from '../utils/hasProp'

export const isBackendUser = (user = {}) => {
const leaService = user.services?.lea
if (!leaService) { return false }
return (
hasProp(leaService, 'id') &&
hasProp(leaService, 'accessToken')
)
}
7 changes: 7 additions & 0 deletions backend/api/accounts/onAccountLoginHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { getUsersCollection } from '../collections/getUsersCollection'

export const onAccountLoginHandler = function ({ user }) {
const userId = user._id
const lastLogin = new Date()
getUsersCollection().update(userId, { $set: { lastLogin } })
}
10 changes: 10 additions & 0 deletions backend/api/accounts/publishDefaultAccountFields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { getUsersCollection } from '../collections/getUsersCollection'

export const publishDefaultAccountFields = function () {
const { userId } = this

// skip this for non-logged in users
if (!userId) return this.ready()

return getUsersCollection().find(userId, { fields: { emails: 0, services: 0, device: 0 } })
}
21 changes: 0 additions & 21 deletions backend/api/accounts/tests/UserEmail.tests.js

This file was deleted.

3 changes: 2 additions & 1 deletion backend/api/accounts/tests/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-env mocha */
describe('accounts', function () {
import './RestoreCodes.tests'
import './UserEmail.tests'
import './onAccountLoginHandler.tests'
import './publishDefaultAccountFields.tests'
})
21 changes: 21 additions & 0 deletions backend/api/accounts/tests/onAccountLoginHandler.tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* eslint-env mocha */
import { expect } from 'chai'
import { restoreCollections, stubCollection } from '../../../tests/helpers/stubCollection'
import { onAccountLoginHandler } from '../onAccountLoginHandler'
import { getUsersCollection } from '../../collections/getUsersCollection'

describe(onAccountLoginHandler.name, function () {
before(() => {
stubCollection([getUsersCollection()])
})
after(() => {
restoreCollections()
})
it('adds the timestamp to the current user', () => {
const userId = getUsersCollection().insert({})
const user = { _id: userId }
onAccountLoginHandler({ user })
const userDoc = getUsersCollection().findOne(userId)
expect(userDoc.lastLogin).to.be.instanceOf(Date)
})
})
30 changes: 30 additions & 0 deletions backend/api/accounts/tests/publishDefaultAccountFields.tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* eslint-env mocha */
import { expect } from 'chai'
import { publishDefaultAccountFields } from '../publishDefaultAccountFields'
import { restoreCollections, stubCollection } from '../../../tests/helpers/stubCollection'
import { getUsersCollection } from '../../collections/getUsersCollection'

describe(publishDefaultAccountFields.name, function () {
before(() => {
stubCollection([getUsersCollection()])
})
after(() => {
restoreCollections()
})
it('skips if no user is authenticated', done => {
publishDefaultAccountFields.call({ ready: done })
})
it('filters sensitive fields', () => {
const userId = getUsersCollection().insert({
username: 'moo',
emails: [{ address: 'foo@bar.com' }],
services: { foo: 'bar' },
device: { platform: 'superOS' }
})
const [userDoc] = publishDefaultAccountFields.call({ userId }).fetch()
expect(userDoc).to.deep.equal({
_id: userId,
username: 'moo'
})
})
})
7 changes: 7 additions & 0 deletions backend/api/app/appTokenIsValid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Meteor } from 'meteor/meteor'
import { SHA256 } from 'meteor/sha'

export const appTokenIsValid = ((src) => {
const appToken = SHA256(src)
return (token) => token === appToken
})(Meteor.settings.app.token)
10 changes: 10 additions & 0 deletions backend/api/collections/tests/getUsersCollection.tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* eslint-env mocha */
import { expect } from 'chai'
import { Meteor } from 'meteor/meteor'
import { getUsersCollection } from '../getUsersCollection'

describe(getUsersCollection.name, function () {
it('returns the Meteor users collection', () => {
expect(getUsersCollection()).to.equal(Meteor.users)
})
})
6 changes: 5 additions & 1 deletion backend/api/collections/tests/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
import './LocalCollections.tests'
/* eslint-env mocha */
describe('collections', function () {
import './LocalCollections.tests'
import './getUsersCollection.tests'
})
50 changes: 50 additions & 0 deletions backend/api/crypto/SensitiveData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Meteor } from 'meteor/meteor'
import crypto from 'node:crypto'

/**
* Represents User Email encrypt/decrypt functionality
* @category api
* @namespace
*/
const SensitiveData = {}

const { algorithm, key, outputFormat } = Meteor.settings.crypto

SensitiveData.validate = value => {
if (typeof value !== 'string' || value.length < 1) {
throw new Error(`Expected valid string with min. length of 1, got ${value}`)
}
}

/**
* Encrypt an existing use ermail
* @param data {string}
* @return {string}
*/
SensitiveData.encrypt = (data) => {
SensitiveData.validate(data)
const iv = crypto.randomBytes(16).toString('hex').slice(0, 16)
const cipher = crypto.createCipheriv(algorithm, key, iv)
let encrypted = cipher.update(data, 'utf8', outputFormat)
encrypted += cipher.final(outputFormat)
encrypted += ':'
encrypted += iv
return encrypted
}

/**
* Decrypts and existing user email
* @param data {string}
* @return {string}
*/
SensitiveData.decrypt = (data) => {
const fields = data.split(':')
const iv = fields[1]
const encrypted = fields[0]
const decipher = crypto.createDecipheriv(algorithm, key, iv)
let decrypted = decipher.update(encrypted, outputFormat, 'utf-8')
decrypted += decipher.final('utf8')
return decrypted
}

export { SensitiveData }
18 changes: 18 additions & 0 deletions backend/api/crypto/tests/SensitiveData.tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* eslint-env mocha */
import { SensitiveData } from '../SensitiveData'
import { expect } from 'chai'

describe('SensitiveData', () => {
it('throws if the input to encrypt is not a valid string', () => {
[undefined, null, '', 1, [], {}, true, () => {}, new Date()].forEach(value => {
expect(() => SensitiveData.encrypt(value)).to.throw(`Expected valid string with min. length of 1, got ${value}`)
})
})
it('check if encryption and decryption works', () => {
expect(SensitiveData.decrypt(SensitiveData.encrypt('a@a.de'))).to.equal('a@a.de')
})
it('check if the IV of encryption is random', () => {
const encryptedEmailWithIV = SensitiveData.encrypt('a@a.de')
expect(SensitiveData.encrypt('a@a.de') === (encryptedEmailWithIV)).to.equal(false)
})
})
Loading

0 comments on commit d2c50e7

Please sign in to comment.