Compare commits
No commits in common. "master" and "2.0.1" have entirely different histories.
@ -12,13 +12,9 @@ SRC_DIR=`dirname $0`"/.."
|
||||
RELEASE_VERSION=${1}
|
||||
echo "Release version set to ${RELEASE_VERSION}"
|
||||
|
||||
#which npm > /dev/null
|
||||
#which gulp > /dev/null
|
||||
#which wget > /dev/null
|
||||
|
||||
sed -ri 's/(.*)<version>(.+)<\/version>/\1<version>'${RELEASE_VERSION}'<\/version>/g' ${SRC_DIR}/appinfo/info.xml
|
||||
npm install
|
||||
node_modules/gulp/bin/gulp.js uglify
|
||||
gulp uglify
|
||||
git commit -am "Release "${RELEASE_VERSION}
|
||||
git tag ${RELEASE_VERSION}
|
||||
git push
|
||||
@ -39,8 +35,7 @@ rm -Rf \
|
||||
ocsms/gulpfile.js \
|
||||
ocsms/package.json \
|
||||
ocsms/.ci \
|
||||
ocsms/.tx \
|
||||
ocsms/doc
|
||||
ocsms/.tx
|
||||
|
||||
tar cfz ocsms-${RELEASE_VERSION}.tar.gz ocsms
|
||||
echo "Release version "${RELEASE_VERSION}" is now ready."
|
||||
|
70
.github/workflows/codeql-analysis.yml
vendored
@ -1,70 +0,0 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '20 1 * * 4'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
11
.l10nignore
@ -1,11 +0,0 @@
|
||||
doc/swagger-ui-bundle.js
|
||||
doc/swagger-ui-bundle.js.map
|
||||
doc/swagger-ui.css
|
||||
doc/swagger-ui.css.map
|
||||
doc/swagger-ui.js
|
||||
doc/swagger-ui.js.map
|
||||
doc/swagger-ui-standalone-preset.js
|
||||
doc/swagger-ui-standalone-preset.js.map
|
||||
doc/swagger.yml
|
||||
doc/index.html
|
||||
doc/oauth2-redirect.html
|
@ -1,10 +1,9 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
lang_map = sk_SK: sk, th_TH: th, ja_JP: ja, bg_BG: bg, cs_CZ: cs, fi_FI: fi, hu_HU: hu, nb_NO: nb
|
||||
lang_map = bg_BG: bg, cs_CZ: cs, fi_FI: fi, hu_HU: hu, nb_NO: nb, sk_SK: sk, th_TH: th, ja_JP: ja
|
||||
|
||||
[o:nextcloud:p:nextcloud:r:ocsms]
|
||||
[nextcloud.ocsms]
|
||||
file_filter = translationfiles/<lang>/ocsms.po
|
||||
source_file = translationfiles/templates/ocsms.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
FROM nextcloud:15.0.0-rc-apache
|
||||
FROM nextcloud:14.0.3-apache
|
||||
|
||||
COPY . /usr/src/nextcloud/apps/ocsms
|
||||
|
15
README.md
@ -1,14 +1,15 @@
|
||||
# Phone Sync (for Nextcloud & ownCloud)
|
||||
|
||||
Phone Sync provides a webinterface to display your SMS conversations. SMS conversations are pushed by your Android devices using the [Android client](https://github.com/nerzhul/ownCloud-SMS-App), available on [F-Droid](https://f-droid.org/repository/browse/?fdid=fr.unix_experience.owncloud_sms).
|
||||
Phone Sync provides a webinterface to display your SMS conversations. SMS conversations are pushed by your Android devices using the [Android client](https://github.com/nerzhul/ownCloud-SMS-App), available on [Google Play Store](https://play.google.com/store/apps/details?id=fr.unix_experience.owncloud_sms).
|
||||
|
||||
## :arrow_forward: Access
|
||||
|
||||
The app is available on the [Nextcloud App Store](https://apps.nextcloud.com/apps/ocsms), so installing is as easy as:
|
||||
The app is available in both, [Nextcloud appstore](https://apps.nextcloud.com/apps/ocsms) and [ownCloud appstore](https://apps.owncloud.com/content/show.php/ownCloud+SMS?content=167289). So installing is as easy as
|
||||
|
||||
1. Navigate in your Nextcloud instance to the "Apps"
|
||||
2. Select the category "Multimedia"
|
||||
3. Click "activate"
|
||||
1. Navigate in your Nextcloud / ownCloud instance to the "apps"
|
||||
2. Enable "experimental apps" in the settings
|
||||
3. Select the category "Multimedia"
|
||||
4. Click "activate"
|
||||
|
||||
## :question: Solve encoding errors on MySQL
|
||||
If you are on MySQL or MariaDB and have the following issue with the database:
|
||||
@ -58,7 +59,3 @@ If you've enabled 2FA (Two Factor Authentication) logins you may be hit with an
|
||||
|
||||
## :notebook: License
|
||||
Phone Sync web application is currently licensed under [AGPL license](https://github.com/nextcloud/ocsms/blob/master/LICENSE.md).
|
||||
|
||||
## :notebook: External Libraries
|
||||
[Twemoji](https://github.com/twitter/twemoji) Code licensed under the [MIT License](http://opensource.org/licenses/MIT), Graphics licensed under [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/).
|
||||
[libphonenumber-for-php](https://github.com/giggsey/libphonenumber-for-php) Code licensed under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0).
|
||||
|
37
appinfo/app.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* Nextcloud - Phone Sync
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Loic Blot <loic.blot@unix-experience.fr>
|
||||
* @copyright Loic Blot 2014-2017
|
||||
*/
|
||||
|
||||
namespace OCA\OcSms\AppInfo;
|
||||
|
||||
if (class_exists('\OCP\AppFramework\App')) {
|
||||
\OC::$server->getNavigationManager()->add(array(
|
||||
// the string under which your app will be referenced in owncloud
|
||||
'id' => 'ocsms',
|
||||
|
||||
// sorting weight for the navigation. The higher the number, the higher
|
||||
// will it be listed in the navigation
|
||||
'order' => 10,
|
||||
|
||||
// the route that will be shown on startup
|
||||
'href' => \OC::$server->getURLGenerator()->linkToRoute('ocsms.sms.index'),
|
||||
|
||||
// the icon that will be shown in the navigation
|
||||
// this file needs to exist in img/
|
||||
'icon' => \OC::$server->getURLGenerator()->imagePath('ocsms', 'app.svg'),
|
||||
|
||||
// the title of your application. This will be used in the
|
||||
// navigation or on the settings page of your app
|
||||
'name' => \OCP\Util::getL10N('ocsms')->t('Phone Sync')
|
||||
));
|
||||
} else {
|
||||
$msg = 'Can not enable the OcSms app because the App Framework App is disabled';
|
||||
\OC::$server->getLogger()->error($msg, array('ocsms'));
|
||||
}
|
268
appinfo/database.xml
Normal file
@ -0,0 +1,268 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<database>
|
||||
<name>*dbname*</name>
|
||||
<create>true</create>
|
||||
<overwrite>false</overwrite>
|
||||
<charset>utf8</charset>
|
||||
|
||||
<table>
|
||||
<name>*dbprefix*ocsms_user_datas</name>
|
||||
<declaration>
|
||||
<field>
|
||||
<name>user_id</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>64</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>datakey</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>64</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>datavalue</name>
|
||||
<type>text</type>
|
||||
<length>64</length>
|
||||
<notnull>true</notnull>
|
||||
</field>
|
||||
<index>
|
||||
<name>user_datas_user_datakey</name>
|
||||
<field>
|
||||
<name>user_id</name>
|
||||
</field>
|
||||
<field>
|
||||
<name>datakey</name>
|
||||
</field>
|
||||
</index>
|
||||
</declaration>
|
||||
</table>
|
||||
<table>
|
||||
<name>*dbprefix*ocsms_smsdatas</name>
|
||||
<declaration>
|
||||
<field>
|
||||
<name>id</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<autoincrement>1</autoincrement>
|
||||
<length>10</length>
|
||||
<primary>true</primary>
|
||||
</field>
|
||||
<field>
|
||||
<name>user_id</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>64</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>added</name>
|
||||
<type>timestamp</type>
|
||||
<notnull>true</notnull>
|
||||
<default>1970-01-01 00:00:00</default>
|
||||
</field>
|
||||
<field>
|
||||
<name>lastmodified</name>
|
||||
<type>timestamp</type>
|
||||
<notnull>true</notnull>
|
||||
<default>1970-01-01 00:00:00</default>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_id</name>
|
||||
<type>integer</type>
|
||||
<notnull>true</notnull>
|
||||
<length>5</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_address</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>512</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_msg</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>10240</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_date</name>
|
||||
<type>integer</type>
|
||||
<notnull>true</notnull>
|
||||
<length>10</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_flags</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<default>00</default>
|
||||
<length>2</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_mailbox</name>
|
||||
<type>integer</type>
|
||||
<notnull>true</notnull>
|
||||
<length>1</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_type</name>
|
||||
<type>integer</type>
|
||||
<notnull>true</notnull>
|
||||
<length>1</length>
|
||||
</field>
|
||||
<index>
|
||||
<name>smsdata_user_mailbox</name>
|
||||
<field>
|
||||
<name>user_id</name>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_mailbox</name>
|
||||
</field>
|
||||
</index>
|
||||
<index>
|
||||
<name>smsdata_user_smsid</name>
|
||||
<field>
|
||||
<name>user_id</name>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_id</name>
|
||||
</field>
|
||||
</index>
|
||||
<index>
|
||||
<name>smsdata_user_mailbox_date</name>
|
||||
<field>
|
||||
<name>user_id</name>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_mailbox</name>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_date</name>
|
||||
</field>
|
||||
</index>
|
||||
<index>
|
||||
<name>smsdata_user_mailbox_address</name>
|
||||
<field>
|
||||
<name>user_id</name>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_mailbox</name>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_address</name>
|
||||
</field>
|
||||
</index>
|
||||
<index>
|
||||
<name>smsdata_user_mailbox_address_date</name>
|
||||
<field>
|
||||
<name>user_id</name>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_mailbox</name>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_address</name>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_date</name>
|
||||
</field>
|
||||
</index>
|
||||
</declaration>
|
||||
</table>
|
||||
<table>
|
||||
<name>*dbprefix*ocsms_sendmessage_queue</name>
|
||||
<declaration>
|
||||
<field>
|
||||
<name>id</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<autoincrement>1</autoincrement>
|
||||
<length>10</length>
|
||||
<primary>true</primary>
|
||||
</field>
|
||||
<field>
|
||||
<name>user_id</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>64</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_address</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>64</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>sms_msg</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>2048</length>
|
||||
</field>
|
||||
</declaration>
|
||||
</table>
|
||||
<table>
|
||||
<name>*dbprefix*ocsms_conversation_read_states</name>
|
||||
<declaration>
|
||||
<field>
|
||||
<name>user_id</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>64</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>phone_number</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>64</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>int_date</name>
|
||||
<type>integer</type>
|
||||
<length>32</length>
|
||||
<notnull>true</notnull>
|
||||
</field>
|
||||
<index>
|
||||
<name>sms_conversation_rs_pkey</name>
|
||||
<field>
|
||||
<name>user_id</name>
|
||||
</field>
|
||||
<field>
|
||||
<name>phone_number</name>
|
||||
</field>
|
||||
</index>
|
||||
</declaration>
|
||||
</table>
|
||||
<table>
|
||||
<name>*dbprefix*ocsms_config</name>
|
||||
<declaration>
|
||||
<field>
|
||||
<name>user</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>255</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>key</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>255</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>value</name>
|
||||
<type>text</type>
|
||||
<notnull>false</notnull>
|
||||
<length>10240</length>
|
||||
</field>
|
||||
<index>
|
||||
<name>config_user_key</name>
|
||||
<field>
|
||||
<name>user</name>
|
||||
</field>
|
||||
<field>
|
||||
<name>key</name>
|
||||
</field>
|
||||
</index>
|
||||
</declaration>
|
||||
</table>
|
||||
</database>
|
@ -5,35 +5,26 @@
|
||||
<name>Phone Sync</name>
|
||||
<summary>An app to sync SMS with your cloud</summary>
|
||||
<description>An app to sync SMS with your cloud</description>
|
||||
<author>Loic Blot</author>
|
||||
<author>e-alfred</author>
|
||||
<version>2.2.0</version>
|
||||
<licence>agpl</licence>
|
||||
<author homepage="https://www.unix-experience.fr">Loic Blot</author>
|
||||
<version>2.0.1</version>
|
||||
<category>multimedia</category>
|
||||
<category>tools</category>
|
||||
<dependencies>
|
||||
<nextcloud min-version="18" max-version="20" />
|
||||
<php min-version="5.6" min-int-size="32"/>
|
||||
<nextcloud min-version="14.0" max-version="14.0" />
|
||||
</dependencies>
|
||||
|
||||
<ocsid>167289</ocsid>
|
||||
|
||||
<website>https://github.com/nextcloud/ocsms</website>
|
||||
<bugs>https://github.com/nextcloud/ocsms/issues</bugs>
|
||||
<repository type="git">https://github.com/nextcloud/ocsms</repository>
|
||||
<screenshot small-thumbnail="https://raw.githubusercontent.com/nextcloud/ocsms/master/appinfo/screenshots/1-small.png">https://raw.githubusercontent.com/nextcloud/ocsms/master/appinfo/screenshots/1.png</screenshot>
|
||||
|
||||
<fulltextsearch>
|
||||
<provider>OCA\OcSms\Provider\FullTextSearchProvider</provider>
|
||||
</fulltextsearch>
|
||||
<repair-steps>
|
||||
<post-migration>
|
||||
<step>OCA\OcSms\Migration\FixConversationReadStates</step>
|
||||
</post-migration>
|
||||
</repair-steps>
|
||||
<navigations>
|
||||
<navigation>
|
||||
<id>ocsms</id>
|
||||
<name>Phone Sync</name>
|
||||
<route>ocsms.sms.index</route>
|
||||
<icon>app.svg</icon>
|
||||
</navigation>
|
||||
</navigations>
|
||||
</info>
|
||||
|
@ -43,7 +43,7 @@ $application->registerRoutes($this, array('routes' => array(
|
||||
array('name' => 'api#fetch_messages_count', 'url' => '/api/v2/messages/count', 'verb' => 'GET'), // Android APIv2
|
||||
|
||||
// Android API v3
|
||||
array('name' => 'api#generate_sms_test_data', 'url' => '/api/v3/test/generate_sms_data', 'verb' => 'POST'), // Android APIv3
|
||||
// @TODO
|
||||
|
||||
// Android API v4
|
||||
// @TODO future calls to sending calls recorded on the phone
|
||||
|
@ -229,25 +229,4 @@ class ApiController extends Controller {
|
||||
// @TODO
|
||||
return new JSONResponse(array("messages" => array()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* @param $smsCount
|
||||
* @param $smsDatas
|
||||
* @return JSONResponse
|
||||
*
|
||||
* produce a bunch of data to test application
|
||||
*/
|
||||
public function generateSmsTestData () {
|
||||
return $this->push(2, array(
|
||||
array("_id" => 702, "type" => 1, "mbox" => 2, "read" => "true",
|
||||
"seen" => "true", "date" => 1654777747, "address" => "+33123456789",
|
||||
"body" => "hello dude"),
|
||||
array("_id" => 685, "type" => 1, "mbox" => 1, "read" => "true",
|
||||
"seen" => "true", "date" => 1654777777, "address" => "+33123456789",
|
||||
"body" => "😀🌍⭐🌎🌔🌒🐕🍖🥂🍻🎮🤸♂️🚇🈲❕📘📚📈🇸🇨🇮🇲"),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -80,21 +80,7 @@ class SmsController extends Controller {
|
||||
$params = array('user' => $this->userId,
|
||||
'mailboxes' => $mboxes
|
||||
);
|
||||
$response = new TemplateResponse($this->appName, 'main', $params);
|
||||
$this->addContentSecurityToResponse($response);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the domain "data:" to the allowed image domains
|
||||
* this function is called by reference
|
||||
*
|
||||
* @param TemplateResponse $response
|
||||
*/
|
||||
private function addContentSecurityToResponse($response) {
|
||||
$csp = new Http\ContentSecurityPolicy();
|
||||
$csp->allowEvalScript(true);
|
||||
$response->setContentSecurityPolicy($csp);
|
||||
return new TemplateResponse($this->appName, 'main', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,10 +3,6 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body.dark #app {
|
||||
color: var(--color-background-dark);
|
||||
}
|
||||
|
||||
#app-navigation {
|
||||
box-sizing: border-box;
|
||||
border-left: 1px solid #ddd;
|
||||
@ -170,10 +166,6 @@ body.dark #app {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.msg-sent a:link, .msg-sent a:visited, .msg-recv a:link, .msg-recv a:visited {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.msg-date {
|
||||
color: #666;
|
||||
font-style: italic;
|
||||
@ -289,13 +281,6 @@ label {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
img.emoji {
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
margin: 0 .05em 0 .1em;
|
||||
vertical-align: -0.1em;
|
||||
}
|
||||
|
||||
.contact-list-no-contact {
|
||||
padding: 1em;
|
||||
font-size: 1.5em;
|
||||
|
@ -26,7 +26,7 @@ class ConversationStateMapper extends Mapper {
|
||||
public function getLast ($userId) {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->selectAlias($qb->createFunction('MAX(int_date)'), 'mx')
|
||||
->from('ocsms_conv_r_states')
|
||||
->from('ocsms_conversation_read_states')
|
||||
->where($qb->expr()->andX(
|
||||
$qb->expr()->eq('user_id', $qb->createNamedParameter($userId))
|
||||
));
|
||||
@ -42,7 +42,7 @@ class ConversationStateMapper extends Mapper {
|
||||
public function getLastForPhoneNumber ($userId, $phoneNumber) {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->selectAlias($qb->createFunction('MAX(int_date)'), 'mx')
|
||||
->from('ocsms_conv_r_states')
|
||||
->from('ocsms_conversation_read_states')
|
||||
->where($qb->expr()->andX(
|
||||
$qb->expr()->eq('user_id', $qb->createNamedParameter($userId)),
|
||||
$qb->expr()->eq('phone_number', $qb->createNamedParameter($phoneNumber))
|
||||
@ -59,7 +59,7 @@ class ConversationStateMapper extends Mapper {
|
||||
public function setLast ($userId, $phoneNumber, $lastDate) {
|
||||
$this->db->beginTransaction();
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->delete('ocsms_conv_r_states')
|
||||
$qb->delete('ocsms_conversation_read_states')
|
||||
->where($qb->expr()->andX(
|
||||
$qb->expr()->eq('user_id', $qb->createNamedParameter($userId)),
|
||||
$qb->expr()->eq('phone_number', $qb->createNamedParameter($phoneNumber))
|
||||
@ -67,7 +67,7 @@ class ConversationStateMapper extends Mapper {
|
||||
$qb->execute();
|
||||
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->insert('ocsms_conv_r_states')
|
||||
$qb->insert('ocsms_conversation_read_states')
|
||||
->values(array(
|
||||
'user_id' => $qb->createNamedParameter($userId),
|
||||
'phone_number' => $qb->createNamedParameter($phoneNumber),
|
||||
|
@ -132,18 +132,14 @@ class SmsMapper extends Mapper {
|
||||
}
|
||||
$phoneList[$fmtPN][$pn] += 1;
|
||||
}
|
||||
$fpn = $phoneNumber;
|
||||
if(isset($phoneList[$fpn])) {
|
||||
$fpn = PhoneNumberFormatter::format($country, $phoneNumber);
|
||||
if(isset($phoneList[$fpn])){
|
||||
return $phoneList[$fpn];
|
||||
}
|
||||
|
||||
$fpn = PhoneNumberFormatter::format($country, $fpn);
|
||||
if (isset($phoneList[$fpn])) {
|
||||
return $phoneList[$fpn];
|
||||
}
|
||||
|
||||
else {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
public function getAllMessagesForPhoneNumber ($userId, $phoneNumber, $country, $minDate = 0) {
|
||||
|
||||
|
Before Width: | Height: | Size: 445 B |
Before Width: | Height: | Size: 1.1 KiB |
@ -1,60 +0,0 @@
|
||||
<!-- HTML for static distribution bundle build -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Swagger UI</title>
|
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
|
||||
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="./swagger-ui-bundle.js"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
// Begin Swagger UI call region
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "https://raw.githubusercontent.com/nextcloud/ocsms/master/doc/swagger.yml",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
// End Swagger UI call region
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,67 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en-US">
|
||||
<body onload="run()">
|
||||
</body>
|
||||
</html>
|
||||
<script>
|
||||
'use strict';
|
||||
function run () {
|
||||
var oauth2 = window.opener.swaggerUIRedirectOauth2;
|
||||
var sentState = oauth2.state;
|
||||
var redirectUrl = oauth2.redirectUrl;
|
||||
var isValid, qp, arr;
|
||||
|
||||
if (/code|token|error/.test(window.location.hash)) {
|
||||
qp = window.location.hash.substring(1);
|
||||
} else {
|
||||
qp = location.search.substring(1);
|
||||
}
|
||||
|
||||
arr = qp.split("&")
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
|
||||
qp = qp ? JSON.parse('{' + arr.join() + '}',
|
||||
function (key, value) {
|
||||
return key === "" ? value : decodeURIComponent(value)
|
||||
}
|
||||
) : {}
|
||||
|
||||
isValid = qp.state === sentState
|
||||
|
||||
if ((
|
||||
oauth2.auth.schema.get("flow") === "accessCode"||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode"
|
||||
) && !oauth2.auth.code) {
|
||||
if (!isValid) {
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "warning",
|
||||
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
|
||||
});
|
||||
}
|
||||
|
||||
if (qp.code) {
|
||||
delete oauth2.state;
|
||||
oauth2.auth.code = qp.code;
|
||||
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
|
||||
} else {
|
||||
let oauthErrorMsg
|
||||
if (qp.error) {
|
||||
oauthErrorMsg = "["+qp.error+"]: " +
|
||||
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
|
||||
(qp.error_uri ? "More info: "+qp.error_uri : "");
|
||||
}
|
||||
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "error",
|
||||
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
|
||||
});
|
||||
}
|
||||
} else {
|
||||
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
|
||||
}
|
||||
window.close();
|
||||
}
|
||||
</script>
|
@ -1 +0,0 @@
|
||||
{"version":3,"sources":[],"names":[],"mappings":"","file":"swagger-ui.css","sourceRoot":""}
|
@ -1,58 +0,0 @@
|
||||
swagger: "2.0"
|
||||
|
||||
info:
|
||||
version: 2.0.0
|
||||
title: OcSMS API
|
||||
description: OcSMS API specification
|
||||
|
||||
schemes:
|
||||
- https
|
||||
host: nextcloud.example.org
|
||||
basePath: /apps/ocsms
|
||||
|
||||
paths:
|
||||
/get/apiversion:
|
||||
get:
|
||||
summary: Retrieve API version
|
||||
description: Returns the current API version.
|
||||
responses:
|
||||
200:
|
||||
description: OcSMS API version
|
||||
schema:
|
||||
required:
|
||||
- version
|
||||
properties:
|
||||
version:
|
||||
type: integer
|
||||
# TODO: complete this
|
||||
/push:
|
||||
post:
|
||||
summary: Push messages to server
|
||||
description: Push a list of messages to the server
|
||||
responses:
|
||||
200:
|
||||
# TODO: complete this
|
||||
/replace:
|
||||
post:
|
||||
summary: Replace messages to server
|
||||
description: Push a list of messages to replace on the server
|
||||
responses:
|
||||
200:
|
||||
# TODO: complete this
|
||||
/get/smsidlist:
|
||||
get:
|
||||
# TODO: complete this
|
||||
/get/lastmsgtime:
|
||||
get:
|
||||
# TODO: complete this
|
||||
/api/v2/phones/list:
|
||||
get:
|
||||
# TODO: complete this
|
||||
/api/v2/messages/{start}/{limit}:
|
||||
get:
|
||||
# TODO: complete this
|
||||
/api/v2/messages/count:
|
||||
get:
|
||||
# Not implemented
|
||||
/api/v4/messages/sendqueue:
|
||||
get:
|
18
gulpfile.js
@ -3,18 +3,14 @@ let concat = require('gulp-concat');
|
||||
let rename = require("gulp-rename");
|
||||
let uglify = require('gulp-uglify-es').default;
|
||||
|
||||
js_files = [
|
||||
'js/devel/app.js',
|
||||
'js/devel/settings.js',
|
||||
'js/devel/contactlist.js',
|
||||
'js/devel/conversation.js',
|
||||
'js/devel/helpers.js',
|
||||
'js/devel/notifications.js'
|
||||
];
|
||||
|
||||
gulp.task("uglify", function () {
|
||||
return gulp.src(js_files)
|
||||
.pipe(concat("app.min.js"))
|
||||
return gulp.src("js/devel/app.js")
|
||||
.pipe(concat('js/devel/settings.js'))
|
||||
.pipe(concat('js/devel/contactlist.js'))
|
||||
.pipe(concat('js/devel/conversation.js'))
|
||||
.pipe(concat('js/devel/helpers.js'))
|
||||
.pipe(concat('js/devel/notifications.js'))
|
||||
.pipe(rename("app.min.js"))
|
||||
.pipe(uglify(/* options */))
|
||||
.pipe(gulp.dest("js/"));
|
||||
});
|
1
js/anchorme.min.js
vendored
2
js/app.min.js
vendored
@ -102,7 +102,6 @@ var Conversation = new Vue({
|
||||
let msgClass = '';
|
||||
let msgCount = 0;
|
||||
let self = this;
|
||||
let twemojiOptions = { base: OC.generateUrl('/apps/ocsms/js/twemoji/')};
|
||||
|
||||
$.each(jsondata["conversation"], function (id, vals) {
|
||||
if (vals["type"] == 1) {
|
||||
@ -125,7 +124,7 @@ var Conversation = new Vue({
|
||||
'id': id,
|
||||
'type': msgClass,
|
||||
'date': new Date(id * 1),
|
||||
'content': twemoji.parse(anchorme(escapeHTML(vals['msg'])), twemojiOptions)
|
||||
'content': vals['msg']
|
||||
});
|
||||
buf = true;
|
||||
msgCount++;
|
||||
|
@ -27,51 +27,3 @@ function toBool(str) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function escapeHTML(string) {
|
||||
var str = '' + string
|
||||
var matchHtmlRegExp = /["'&<>]/
|
||||
var match = matchHtmlRegExp.exec(str)
|
||||
|
||||
if (!match) {
|
||||
return str
|
||||
}
|
||||
|
||||
var escape
|
||||
var html = ''
|
||||
var index = 0
|
||||
var lastIndex = 0
|
||||
|
||||
for (index = match.index; index < str.length; index++) {
|
||||
switch (str.charCodeAt(index)) {
|
||||
case 34: // "
|
||||
escape = '"'
|
||||
break
|
||||
case 38: // &
|
||||
escape = '&'
|
||||
break
|
||||
case 39: // '
|
||||
escape = '''
|
||||
break
|
||||
case 60: // <
|
||||
escape = '<'
|
||||
break
|
||||
case 62: // >
|
||||
escape = '>'
|
||||
break
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
if (lastIndex !== index) {
|
||||
html += str.substring(lastIndex, index)
|
||||
}
|
||||
|
||||
lastIndex = index + 1
|
||||
html += escape
|
||||
}
|
||||
|
||||
return lastIndex !== index
|
||||
? html + str.substring(lastIndex, index)
|
||||
: html
|
||||
}
|
||||
|
Before Width: | Height: | Size: 551 B |
Before Width: | Height: | Size: 923 B |
Before Width: | Height: | Size: 557 B |
Before Width: | Height: | Size: 458 B |
Before Width: | Height: | Size: 562 B |
Before Width: | Height: | Size: 403 B |
Before Width: | Height: | Size: 682 B |
Before Width: | Height: | Size: 561 B |
Before Width: | Height: | Size: 603 B |
Before Width: | Height: | Size: 517 B |
Before Width: | Height: | Size: 495 B |
Before Width: | Height: | Size: 668 B |
Before Width: | Height: | Size: 670 B |
Before Width: | Height: | Size: 640 B |
Before Width: | Height: | Size: 722 B |
Before Width: | Height: | Size: 553 B |
Before Width: | Height: | Size: 747 B |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 697 B |
Before Width: | Height: | Size: 287 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 849 B |
Before Width: | Height: | Size: 989 B |
Before Width: | Height: | Size: 662 B |
Before Width: | Height: | Size: 245 B |
Before Width: | Height: | Size: 723 B |
Before Width: | Height: | Size: 481 B |
Before Width: | Height: | Size: 453 B |
Before Width: | Height: | Size: 847 B |
Before Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 835 B |
Before Width: | Height: | Size: 387 B |
Before Width: | Height: | Size: 230 B |
Before Width: | Height: | Size: 402 B |
Before Width: | Height: | Size: 559 B |
Before Width: | Height: | Size: 652 B |
Before Width: | Height: | Size: 406 B |
Before Width: | Height: | Size: 336 B |
Before Width: | Height: | Size: 233 B |
Before Width: | Height: | Size: 390 B |
Before Width: | Height: | Size: 244 B |
Before Width: | Height: | Size: 411 B |
Before Width: | Height: | Size: 940 B |
Before Width: | Height: | Size: 279 B |
Before Width: | Height: | Size: 978 B |
Before Width: | Height: | Size: 919 B |
Before Width: | Height: | Size: 884 B |
Before Width: | Height: | Size: 666 B |
Before Width: | Height: | Size: 871 B |
Before Width: | Height: | Size: 805 B |
Before Width: | Height: | Size: 419 B |
Before Width: | Height: | Size: 1000 B |
Before Width: | Height: | Size: 270 B |
Before Width: | Height: | Size: 214 B |
Before Width: | Height: | Size: 669 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 459 B |
Before Width: | Height: | Size: 445 B |
Before Width: | Height: | Size: 706 B |
Before Width: | Height: | Size: 602 B |
Before Width: | Height: | Size: 389 B |
Before Width: | Height: | Size: 356 B |
Before Width: | Height: | Size: 220 B |
Before Width: | Height: | Size: 233 B |
Before Width: | Height: | Size: 961 B |
Before Width: | Height: | Size: 394 B |