diff --git a/.deploy/docker/entrypoint.sh b/.deploy/docker/entrypoint.sh index 1fe40d142e..4ff9f805a1 100755 --- a/.deploy/docker/entrypoint.sh +++ b/.deploy/docker/entrypoint.sh @@ -54,6 +54,7 @@ if [[ ! -z "$DB_PORT" ]]; then fi #env $(grep -v "^\#" .env | xargs) php artisan cache:clear +php artisan firefly-iii:create-database php artisan migrate --seed php artisan firefly-iii:decrypt-all diff --git a/.deploy/kubernetes/firefly-iii.yaml b/.deploy/kubernetes/firefly-iii.yaml new file mode 100644 index 0000000000..925d157c8a --- /dev/null +++ b/.deploy/kubernetes/firefly-iii.yaml @@ -0,0 +1,99 @@ +apiVersion: v1 +kind: Service +metadata: + name: firefly-iii + labels: + app: firefly-iii +spec: + ports: + - port: 80 + selector: + app: firefly-iii + tier: frontend + type: LoadBalancer +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: firefly-iii-export-claim + labels: + app: firefly-iii +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Gi +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: firefly-iii-upload-claim + labels: + app: firefly-iii +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: firefly-iii + labels: + app: firefly-iii +spec: + selector: + matchLabels: + app: firefly-iii + tier: frontend + strategy: + type: Recreate + template: + metadata: + labels: + app: firefly-iii + tier: frontend + spec: + containers: + - image: jc5x/firefly-iii + name: firefly-iii + env: + - name: APP_ENV + value: "local" + - name: APP_KEY + valueFrom: + secretKeyRef: + name: firefly-iii-secrets + key: app_key + - name: DB_HOST + value: firefly-iii-mysql + - name: DB_CONNECTION + value: mysql + - name: DB_DATABASE + value: "fireflyiii" + - name: DB_USERNAME + value: "root" + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: firefly-iii-secrets + key: db_password + ports: + - containerPort: 80 + name: firefly-iii + volumeMounts: + - mountPath: "/var/www/firefly-iii/storage/export" + name: firefly-iii-export + - mountPath: "/var/www/firefly-iii/storage/upload" + name: firefly-iii-upload + imagePullPolicy: Always + volumes: + - name: firefly-iii-export + persistentVolumeClaim: + claimName: firefly-iii-export-claim + - name: firefly-iii-upload + persistentVolumeClaim: + claimName: firefly-iii-upload-claim \ No newline at end of file diff --git a/.deploy/kubernetes/firefly.yaml b/.deploy/kubernetes/firefly.yaml deleted file mode 100644 index 1dc6309e84..0000000000 --- a/.deploy/kubernetes/firefly.yaml +++ /dev/null @@ -1,82 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: mysql-pv-export-claim - labels: - app: firefly-local -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 20Gi ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: mysql-pv-upload-claim - labels: - app: firefly-local -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 20Gi ---- -apiVersion: apps/v1beta1 -kind: Deployment -metadata: - name: firefly-local - namespace: firefly - labels: - app: firefly-local -spec: - selector: - matchLabels: - app: firefly-local - template: - metadata: - labels: - app: firefly-local - spec: - containers: - - image: firefly-local - name: firefly-local - env: - - name: APP_ENV - value: "local" - - name: APP_KEY - value: "S0m3R@nd0mString0f32Ch@rsEx@ct1y" - - name: DB_HOST - value: "172.17.0.9" - - name: DB_NAME - value: "firefly_db" - - name: DB_USER - value: "firefly_db" - - name: DB_PASSWORD - value: "password" - volumeMounts: - - mountPath: "/var/www/firefly-iii/storage/export" - name: mysql-persistent-export - - mountPath: "/var/www/firefly-iii/storage/upload" - name: mysql-persistent-upload - imagePullPolicy: IfNotPresent - volumes: - - name: mysql-persistent-export - persistentVolumeClaim: - claimName: mysql-pv-export-claim - - name: mysql-persistent-upload - persistentVolumeClaim: - claimName: mysql-pv-upload-claim ---- -apiVersion: v1 -kind: Service -metadata: - name: firefly-local -spec: - ports: - - port: 80 - type: NodePort - selector: - app: firefly-local \ No newline at end of file diff --git a/.deploy/kubernetes/kustomization.yaml b/.deploy/kubernetes/kustomization.yaml new file mode 100644 index 0000000000..8c8b856cee --- /dev/null +++ b/.deploy/kubernetes/kustomization.yaml @@ -0,0 +1,8 @@ +resources: + - mysql.yaml + - firefly-iii.yaml +secretGenerator: +- name: firefly-iii-secrets + literals: + - db_password=CHANGEMECHANGEME + - app_key=CHANGEMECHANGEMECHANGEMECHANGEME diff --git a/.deploy/kubernetes/mysql.yaml b/.deploy/kubernetes/mysql.yaml new file mode 100644 index 0000000000..2cbd4938f4 --- /dev/null +++ b/.deploy/kubernetes/mysql.yaml @@ -0,0 +1,65 @@ +apiVersion: v1 +kind: Service +metadata: + name: firefly-iii-mysql + labels: + app: firefly-iii +spec: + ports: + - port: 3306 + selector: + app: firefly-iii + tier: mysql + clusterIP: None +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: mysql-pv-claim + labels: + app: firefly-iii +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: firefly-iii-mysql + labels: + app: firefly-iii +spec: + selector: + matchLabels: + app: firefly-iii + tier: mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: firefly-iii + tier: mysql + spec: + containers: + - image: mysql:5.6 + name: mysql + env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: firefly-iii-secrets + key: db_password + ports: + - containerPort: 3306 + name: mysql + volumeMounts: + - name: mysql-persistent-storage + mountPath: /var/lib/mysql + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim \ No newline at end of file diff --git a/.deploy/kubernetes/sql.yaml b/.deploy/kubernetes/sql.yaml deleted file mode 100644 index aae5f7d5cb..0000000000 --- a/.deploy/kubernetes/sql.yaml +++ /dev/null @@ -1,49 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: sql-pass -type: Opaque -data: - password: cGFzc3dvcmQ= ---- -apiVersion: apps/v1beta1 -kind: Deployment -metadata: - name: mysql - namespace: firefly - labels: - app: mysql -spec: - selector: - matchLabels: - app: mysql - template: - metadata: - labels: - app: mysql - spec: - containers: - - image: mysql - imagePullPolicy: IfNotPresent - name: mysql - env: - - name: MYSQL_ROOT_PASSWORD - valueFrom: - secretKeyRef: - name: sql-pass - key: password - ports: - - containerPort: 3306 - name: mysql ---- -apiVersion: v1 -kind: Service -metadata: - name: mysql -spec: - ports: - - port: 3306 - type: NodePort - selector: - app: mysql - diff --git a/.travis.yml b/.travis.yml index be5b894da0..8036c31257 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,21 +14,21 @@ jobs: include: - dist: xenial arch: amd64 - env: ARCH=amd64 CHANNEL=beta VERSION=4.8.2-beta.1 + env: ARCH=amd64 CHANNEL=alpha VERSION=4.8.2-alpha.5 stage: build script: ./.deploy/docker/travis.sh - dist: xenial arch: amd64 - env: ARCH=arm CHANNEL=beta VERSION=4.8.2-beta.1 + env: ARCH=arm CHANNEL=alpha VERSION=4.8.2-alpha.5 stage: build script: ./.deploy/docker/travis.sh - dist: xenial arch: arm64 - env: ARCH=arm64 CHANNEL=beta VERSION=4.8.2-beta.1 + env: ARCH=arm64 CHANNEL=alpha VERSION=4.8.2-alpha.5 stage: build script: ./.deploy/docker/travis.sh - dist: xenial arch: amd64 - env: CHANNEL=beta VERSION=4.8.2-beta.1 + env: CHANNEL=alpha VERSION=4.8.2-alpha.5 stage: manifest script: ./.deploy/docker/manifest.sh \ No newline at end of file diff --git a/app/Console/Commands/CreateDatabase.php b/app/Console/Commands/CreateDatabase.php new file mode 100644 index 0000000000..613561fe2f --- /dev/null +++ b/app/Console/Commands/CreateDatabase.php @@ -0,0 +1,75 @@ +info('This command currently applies to MySQL connections only.'); + } + // try to set up a raw connection: + $dsn = sprintf('mysql:host=%s;charset=utf8mb4', env('DB_HOST')); + $options = [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::ATTR_EMULATE_PREPARES => false, + ]; + try { + $pdo = new PDO($dsn, env('DB_USERNAME'), env('DB_PASSWORD'), $options); + } catch (PDOException $e) { + $this->error(sprintf('Error when connecting to DB: %s', $e->getMessage())); + + return 1; + } + // with PDO, try to list DB's ( + $stmt = $pdo->query('SHOW DATABASES;'); + $exists = false; + // slightly more complex but less error prone. + foreach ($stmt as $row) { + $name = $row['Database'] ?? false; + if ($name === env('DB_DATABASE')) { + $exists = true; + } + } + if (false === $exists) { + $this->error(sprintf('Database "%s" does not exist.', env('DB_DATABASE'))); + + // try to create it. + $pdo->exec(sprintf('CREATE DATABASE `%s` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;', env('DB_DATABASE'))); + $this->info(sprintf('Created database "%s"', env('DB_DATABASE'))); + + return 0; + } + $this->info(sprintf('Database "%s" exists.', env('DB_DATABASE'))); + + return 0; + } +} diff --git a/app/Http/Requests/RuleFormRequest.php b/app/Http/Requests/RuleFormRequest.php index 7491f5ce3b..a6d204cd3d 100644 --- a/app/Http/Requests/RuleFormRequest.php +++ b/app/Http/Requests/RuleFormRequest.php @@ -89,7 +89,7 @@ class RuleFormRequest extends Request 'triggers.*.type' => 'required|in:' . implode(',', $validTriggers), 'triggers.*.value' => sprintf('required_if:triggers.*.type,%s|min:1|ruleTriggerValue', $contextTriggers), 'actions.*.type' => 'required|in:' . implode(',', $validActions), - 'actions.*.value' => sprintf('required_if:actions.*.type,%s|min:1|ruleActionValue', $contextActions), + 'actions.*.value' => sprintf('required_if:actions.*.type,%s|min:0|max:255|ruleActionValue', $contextActions), 'strict' => 'in:0,1', ]; diff --git a/app/Import/Converter/BankDebitCredit.php b/app/Import/Converter/BankDebitCredit.php index 3e78057aca..ce787fcb08 100644 --- a/app/Import/Converter/BankDebitCredit.php +++ b/app/Import/Converter/BankDebitCredit.php @@ -49,6 +49,7 @@ class BankDebitCredit implements ConverterInterface 'DR', // https://old.reddit.com/r/FireflyIII/comments/bn2edf/generic_debitcredit_indicator/ 'Af', // ING (NL). 'Debet', // Triodos (NL) + 'S', // "Soll", German term for debit ]; if (in_array(trim($value), $negative, true)) { return -1; diff --git a/app/Import/Storage/ImportArrayStorage.php b/app/Import/Storage/ImportArrayStorage.php index 68e6d256d5..663c8ba89a 100644 --- a/app/Import/Storage/ImportArrayStorage.php +++ b/app/Import/Storage/ImportArrayStorage.php @@ -442,7 +442,8 @@ class ImportArrayStorage Log::debug(sprintf('Comparison is a hit! (%s)', $hits)); // compare description: - $comparison = '(empty description)' === $transfer['description'] ? '' : $transfer['description']; + // $comparison = '(empty description)' === $transfer['description'] ? '' : $transfer['description']; + $comparison = $transfer['description']; Log::debug(sprintf('Comparing "%s" to "%s" (original: "%s")', $description, $transfer['description'], $comparison)); if ($description !== $comparison) { Log::debug('Description is not a match, continue with next transfer.'); diff --git a/composer.json b/composer.json index 97e54123ff..01e0e3033c 100644 --- a/composer.json +++ b/composer.json @@ -87,7 +87,8 @@ "pragmarx/google2fa": "6.1.3", "pragmarx/google2fa-laravel": "1.*", "pragmarx/recovery": "^0.1.0", - "rcrowe/twigbridge": "0.9.*" + "rcrowe/twigbridge": "0.9.*", + "ext-pdo": "*" }, "require-dev": { "barryvdh/laravel-ide-helper": "2.*", diff --git a/config/firefly.php b/config/firefly.php index 4d4712ec29..eb851e10b5 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -125,7 +125,7 @@ return [ 'is_demo_site' => false, ], 'encryption' => null === env('USE_ENCRYPTION') || env('USE_ENCRYPTION') === true, - 'version' => '4.8.2-beta.1', + 'version' => '4.8.2-alpha.5', 'api_version' => '0.10.5', 'db_version' => 11, 'maxUploadSize' => 15242880, @@ -480,8 +480,8 @@ return [ 'append_notes', 'prepend_notes', 'link_to_bill', - 'convert_withdrawal', - 'convert_deposit', + //'convert_withdrawal', + //'convert_deposit', 'convert_transfer', ], 'context-rule-triggers' => [