sysPass Version
devel-3.0 218a481 * [FIX] Minor bugfixes
Describe the bug
Empty request response from API.
The requests work fine with the demo and so does the responses.
The requests work fine with our server however we get empty responses.
To Reproduce
Steps to reproduce the behavior:
curl -H 'Content-Type: application/json' -X POST -d '{"jsonrpc": "2.0","method":"account/search", "id" : "1", "params": {"authToken": "ADMIN_API_KEY", "text": "all"}}' https://server-sys.net/sysPass/api.php
or via this python script:
class SyspassClient:
def __init__(self, API_KEY = None, API_URL = None):
self.API_KEY = API_KEY
self.API_URL = API_URL
self.rId = 1
def getAccountSearch(self, text,
count = None,
categoryId = None,
clientId = None):
"""
"""
data = { "jsonrpc": "2.0",
"method": "account/search",
"params": {
"authToken": self.API_KEY,
"text": text,
"count": count,
"categoryId": categoryId,
"clientId": clientId},
"id": self.rId }
self.rId+=1
req = requests.post(self.API_URL, json = data, verify = False)
return req.json()['result']['result'][0]
def getAccountPassword(self, uId, tokenPass):
"""
"""
print("pass: " + tokenPass)
data = {"jsonrpc": "2.0",
"method": "account/viewPass",
"params":{
"authToken": self.API_KEY,
"id": uId,
"tokenPass": tokenPass
},
"id": self.rId
}
self.rId+=1
req = requests.post(self.API_URL, json = data, verify = False)
print("debug : " + repr(req.json()))
return req.json()['result']['result']
if __name__ == '__main__':
client = SyspassClient(API_URL= "http://server-sys.net/sysPass/api.php",
API_KEY = "MY_API_KEY")
user = client.getAccountSearch(text = "all", count = 1)
uId = user['id']
print("uId = " + str(uId) + " client = " + str(user))
password = client.getAccountPassword(uId = uId, tokenPass = "API_viewPass_Password" )['password']
print(password)
Expected behavior
Demo output:
Curl:
request.json()
{"jsonrpc":"2.0","result":{"itemId":0,"result":[{"id":35,"userId":2,"userGroupId":1,"userEditId":0,"name":"dd","clientId":12,"categoryId":11,"login":"dd_user","url":"dd_url","notes":"dd_notes","otherUserEdit":0,"otherUserGroupEdit":0,"isPrivate":0,"isPrivateGroup":0,"dateEdit":null,"passDate":1532703827,"passDateChange":0,"parentId":0,"categoryName":"dd_cat","clientName":"dd_client","userGroupName":"Admins","userName":"sysPass demo","userLogin":"demo","userEditName":"","userEditLogin":"","num_files":0,"publicLinkHash":null,"publicLinkDateExpire":null,"publicLinkTotalCountViews":null,"countView":2}],"resultCode":0,"count":1},"id":1}
Python script:
uId = 35 client = {u'otherUserEdit': 0, u'userId': 2, u'countView': 2, u'id': 35, u'userGroupName': u'Admins', u'userLogin': u'demo', u'publicLinkDateExpire': None, u'parentId': 0, u'isPrivate': 0, u'otherUserGroupEdit': 0, u'userEditId': 0, u'categoryId': 11, u'categoryName': u'dd_cat', u'userEditName': u'', u'passDate': 1532703827, u'isPrivateGroup': 0, u'passDateChange': 0, u'publicLinkHash': None, u'userName': u'sysPass demo', u'userEditLogin': u'', u'name': u'dd', u'url': u'dd_url', u'notes': u'dd_notes', u'clientId': 12, u'publicLinkTotalCountViews': None, u'num_files': 0, u'userGroupId': 1, u'dateEdit': None, u'login': u'dd_user', u'clientName': u'dd_client'}
pass: L(]75zh%jw路F
debug : {u'jsonrpc': u'2.0', u'result': {u'itemId': 0, u'count': 2, u'resultCode': 0, u'result': {u'itemId': 35, u'password': u'dd_psswd'}}, u'id': 2}
dd_psswd
Screenshots
Refer to related issue https://github.com/nuxsmin/sysPass/issues/994#issuecomment-408407270
Event log
Refer to related issue https://github.com/nuxsmin/sysPass/issues/994
Platform (please complete the following information):
Additional context
Related issue: https://github.com/nuxsmin/sysPass/issues/994
Site has https certificate let's encrypt
Web server Nginx
Hello,
I've done some successful tests using this code:
import requests
class SearchRequest:
text = None
count = 10
categoryId = None
clientId = None
def __init__(self):
self.method = "account/search"
def get_payload(self):
out = {'count': self.count}
if self.text is not None:
out['text'] = self.text
if self.categoryId is not None:
out['categoryId'] = self.categoryId
if self.clientId is not None:
out['clientId'] = self.clientId
return out
class Api:
def __init__(self):
self.url = 'http://localhost:10080/api.php'
self.token = '2cee8b224f48e01ef48ac172e879cc7825800a9d7ce3b23783212f4758f1c146'
def search_accounts(self):
search = SearchRequest()
search.text = 'test'
r = requests.post(self.url, json=self.get_request(search.method, search.get_payload()))
return r.json()
def get_request(self, method, params):
params['authToken'] = self.token
return {
'jsonrpc': 2.0,
'method': method,
'params': params,
'id': 1
}
if __name__ == '__main__':
api = Api()
print api.search_accounts()
Could you give a try using it?
OT: Wow...I've just noticed this is the issue number 1000!!...unfortunately, there are no gifts here ;)
@nuxsmin
I wish you had some kind of cake to give me for this milestone though x).
Concerning your code:
Same as mine, it works fine on the demo but on our server I still get the empty json error:
Traceback (most recent call last):
File "test_nuxs.py", line 54, in <module>
print api.search_accounts()
File "test_nuxs.py", line 39, in search_accounts
return r.json()
File "/home/ggousseaud/.local/lib/python2.7/site-packages/requests/models.py", line 896, in json
return complexjson.loads(self.text, **kwargs)
File "/usr/lib/python2.7/json/__init__.py", line 339, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 364, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
Here's my php_err.log:
[03-Aug-2018 12:03:00 Europe/Paris] [DEBUG] [SP\Config\Config::initialize] Config l\
oaded
[03-Aug-2018 12:03:00 Europe/Paris] [DEBUG] [SP\Bootstrap::run] ------------
[03-Aug-2018 12:03:00 Europe/Paris] [DEBUG] [SP\Bootstrap::run] Boostrap:api
[03-Aug-2018 12:03:00 Europe/Paris] [DEBUG] [SP\Bootstrap::SP\{closure}] SP\Modules\
\Api\Controllers\IndexController::indexAction
[03-Aug-2018 12:03:00 Europe/Paris] [EXCEPTION] [N/A] Oops, it looks like this cont\
ent doesn't exist...
#0 [internal function]: SP\Bootstrap->SP\{closure}(Object(Klein\Request), Object(Kl\
ein\Response), Object(Klein\ServiceProvider), Object(Klein\App), Object(Klein\Klein\
), Object(Klein\DataCollection\RouteCollection), Array)
#1 /home/sites/docroot/sysPass/vendor/klein/klein/src/Klein/Klein.php(886): call_us\
er_func(Object(Closure), Object(Klein\Request), Object(Klein\Response), Object(Klei\
n\ServiceProvider), Object(Klein\App), Object(Klein\Klein), Object(Klein\DataCollec\
tion\RouteCollection), Array)
#2 /home/sites/docroot/sysPass/vendor/klein/klein/src/Klein/Klein.php(588): Klein\K\
lein->handleRouteCallback(Object(Klein\Route), Object(Klein\DataCollection\RouteCol\
lection), Array)
#3 /home/sites/docroot/sysPass/lib/SP/Bootstrap.php(436): Klein\Klein->dispatch(Obj\
ect(Klein\Request))
#4 /home/sites/docroot/sysPass/lib/Base.php(72): SP\Bootstrap::run(Object(DI\Contai\
ner))
#5 /home/sites/docroot/sysPass/api.php(28): require('/home/sites/d...')
#6 {main}
Looks like this time it doesn't manage to connect to the method itself. We've pulled and it's up to date.
Using my previous curl method I get this in my php_err.log:
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Config\Config::initialize] Config loaded
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Bootstrap::run] ------------
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Bootstrap::run] Boostrap:api
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Bootstrap::initializeCommon] initializeCommon
[03-Aug-2018 12:19:05 Europe/Paris] [INFO] [SP\Core\PhpExtensionChecker::checkMandatory] Extensions checked
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Core\Language::setLocales] Locale set to: en_US.utf8
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Modules\Api\Init::initialize] initialize
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Core\Language::setLocales] Locale set to: fr_FR.utf8
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Core\Events\EventDispatcherBase::attach] Attach: SP\Providers\Log\DatabaseLogHandler
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Core\Events\EventDispatcherBase::attach] Attach: SP\Providers\Log\FileLogHandler
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Core\Events\EventDispatcherBase::attach] Attach: SP\Providers\Notification\NotificationHandler
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Bootstrap::SP\{closure}] Routing call: SP\Modules\Api\Controllers\AccountController::searchAction
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Providers\Log\FileLogHandler::updateEvent] database.query;SELECT id, userId
FROM Track
WHERE `time` >= ?
AND (ipv4 = ? OR ipv6 = ?)
AND `source` = ?;
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Providers\Log\FileLogHandler::updateEvent] database.query;SELECT id, actionId, userId, vault, `hash`, token
FROM AuthToken
WHERE actionId = ?
AND token = ? LIMIT 1;
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Providers\Log\FileLogHandler::updateEvent] database.query;SELECT U.id,
U.name,
U.userGroupId,
UG.name AS userGroupName,
U.login,
U.ssoLogin,
U.email,
U.notes,
U.loginCount,
U.userProfileId,
U.lastLogin,
U.lastUpdate,
U.lastUpdateMPass,
U.preferences,
U.pass,
U.hashSalt,
U.mPass,
U.mKey,
U.isAdminApp,
U.isAdminAcc,
U.isLdap,
U.isDisabled,
U.isChangePass,
U.isChangedPass,
U.isMigrate
FROM User U
INNER JOIN UserGroup UG ON U.userGroupId = UG.id
WHERE U.id = ? LIMIT 1;
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Providers\Log\FileLogHandler::updateEvent] database.query;SELECT id, `name`, `profile` FROM UserProfile WHERE id = ? LIMIT 1;
[03-Aug-2018 12:19:05 Europe/Paris] [DEBUG] [SP\Providers\Log\FileLogHandler::updateEvent] database.query;SELECT DISTINCT Account.* FROM account_search_v Account WHERE (((Account.isPrivate IS NULL OR Account.isPrivate = 0 OR (Account.isPrivate = 1 AND Account.userId = ?)) AND (Account.isPrivateGroup IS NULL OR Account.isPrivateGroup = 0 OR (Account.isPrivateGroup = 1 AND Account.userGroupId = ?)))) AND ((Account.name LIKE ? OR Account.login LIKE ? OR Account.url LIKE ? OR Account.notes LIKE ?)) ORDER BY Account.clientName, Account.name ASC LIMIT ?, ?;
However still an empty response from the server.
Hey!
regarding the first excerpt, it's looking for IndexController, so it isn't decoding the method indeed.
The latter, it seems that the db accounts search query is performed since account_search_v is the view used for retrieving the accounts.
Is there any proxy between sysPass and tha API client?. If so, it could be stripping out some request data.
Hayo Nuxs,
Nope, no proxy between the client and the server. I don't have any other clue concerning this matter for now, I'm currently testing out the API on the demo, I'll post an issue concerning the problems I've found soon.
I'll keep in touch and tell you if I find anything.
If you need more info I'm here.
Edit: Is there any permission you have to give for the API to work properly?
Hi!
I found the root of this issue. When an exception was thrown by the API (ie. unknown method or missing parameters) it returned the JSON message and then it was picking for the next route available (ie. api.php is the first route and index.php is the second one) because the latter was using a broader regex (index\.php)?. Sorry for the technical details, but I thought it should be explained...
Thanks for the feedback and testing!
Great! I'll be testing that tomorrow and tell you how it went ;)
Keep up the great work mate.
I have a bad and a good news @nuxsmin .
Good news, the behavior concerning python seems to have changed?
Bad news, still empty responses from the server and the behavior that changed is quite peculiar, only changed the python one.
Python php_err.log:
[10-Aug-2018 10:36:56 Europe/Paris] [DEBUG] [SP\Config\Config::initialize] Config loaded
[10-Aug-2018 10:36:56 Europe/Paris] [DEBUG] [SP\Bootstrap::run] ------------
[10-Aug-2018 10:36:56 Europe/Paris] [DEBUG] [SP\Bootstrap::run] Boostrap:api
Seems like it stops at the boostrap?
Curl php_err.log:
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Config\Config::initialize] Config loaded
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Bootstrap::run] ------------
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Bootstrap::run] Boostrap:api
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Bootstrap::initializeCommon] initializeCommon
[10-Aug-2018 10:41:08 Europe/Paris] [INFO] [SP\Core\PhpExtensionChecker::checkMandatory] Extensions checked
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Core\Language::setLocales] Locale set to: en_US.utf8
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Modules\Api\Init::initialize] initialize
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Core\Language::setLocales] Locale set to: fr_FR.utf8
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Core\Events\EventDispatcherBase::attach] Attach: SP\Providers\Log\DatabaseLogHandler
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Core\Events\EventDispatcherBase::attach] Attach: SP\Providers\Log\FileLogHandler
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Core\Events\EventDispatcherBase::attach] Attach: SP\Providers\Notification\NotificationHandler
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Bootstrap::SP\{closure}] Routing call: SP\Modules\Api\Controllers\AccountController::searchAction
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Providers\Log\FileLogHandler::updateEvent] database.query;SELECT id, userId
FROM Track
WHERE `time` >= ?
AND (ipv4 = ? OR ipv6 = ?)
AND `source` = ?;
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Providers\Log\FileLogHandler::updateEvent] database.query;SELECT id, actionId, userId, vault, `hash`, token
FROM AuthToken
WHERE actionId = ?
AND token = ? LIMIT 1;
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Providers\Log\FileLogHandler::updateEvent] database.query;SELECT U.id,
U.name,
U.userGroupId,
UG.name AS userGroupName,
U.login,
U.ssoLogin,
U.email,
U.notes,
U.loginCount,
U.userProfileId,
U.lastLogin,
U.lastUpdate,
U.lastUpdateMPass,
U.preferences,
U.pass,
U.hashSalt,
U.mPass,
U.mKey,
U.isAdminApp,
U.isAdminAcc,
U.isLdap,
U.isDisabled,
U.isChangePass,
U.isChangedPass,
U.isMigrate
FROM User U
INNER JOIN UserGroup UG ON U.userGroupId = UG.id
WHERE U.id = ? LIMIT 1;
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Providers\Log\FileLogHandler::updateEvent] database.query;SELECT id, `name`, `profile` FROM UserProfile WHERE id = ? LIMIT 1;
[10-Aug-2018 10:41:08 Europe/Paris] [DEBUG] [SP\Providers\Log\FileLogHandler::updateEvent] database.query;SELECT DISTINCT Account.* FROM account_search_v Account WHERE (((Account.isPrivate IS NULL OR Account.isPrivate = 0 OR (Account.isPrivate = 1 AND Account.userId = ?)) AND (Account.isPrivateGroup IS NULL OR Account.isPrivateGroup = 0 OR (Account.isPrivateGroup = 1 AND Account.userGroupId = ?)))) AND ((Account.name LIKE ? OR Account.login LIKE ? OR Account.url LIKE ? OR Account.notes LIKE ?)) ORDER BY Account.clientName, Account.name ASC LIMIT ?, ?;
Still empty responses though.
Hi, by empty response, do you mean no JSON payload at all?. It seems that the API user does not have permission on the accounts?. Be aware that same permissions are applied through either web or API .
Hello nuxs,
Looks like we're getting there, I am indeed getting a 405 response [Method not allowed] from my server when using my code (which works with the demo).
Here's a sample of the code I am using that is currently being stimulated by these tests:
class SyspassClient:
def __init__(self, API_KEY, API_URL):
self.API_KEY = API_KEY
self.API_URL = API_URL
self.rId = 1
def AccountSearch(self, text,
count = None,
categoryId = None,
clientId = None):
"""
"""
data = { "jsonrpc": "2.0",
"method": "account/search",
"params": {
"authToken": self.API_KEY,
"text": text,
"count": count,
"categoryId": categoryId,
"clientId": clientId},
"id": self.rId }
self.rId+=1
req = requests.post(self.API_URL, json = data, verify = False)
#return req.json()['result']['result'][0]
return req
I did the tests with the demo and 2 different users in my server, here are my server user auths:

Both users are allowed to search for accounts.
Now here's what happening for admin:
Execution:

php_err.log

For US1:
Execution:

php_err.log:

For the demo output:
Execution:

Looks like I can't be authorized to make these calls even though my authorizations are correctly set.
When I directly make a curl request such as:
curl -H 'Content-Type: application/json' -X POST -d '{"jsonrpc": "2.0","method":"account/search", "id" : "1", "params": {"authToken": "ADMIN_API_KEY", "text": "all"}}' https://syspass-server.net/sysPass/api.php
I get this in :
php_err.log:
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Config\Config::initialize] Config loaded
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Bootstrap::run] ------------
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Bootstrap::run] Boostrap:api
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Bootstrap::initializeCommon] initializeCommon
[16-Aug-2018 11:05:59 Europe/Paris] [INFO] [SP\Core\PhpExtensionChecker::checkMandatory] Extensions checked
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Core\Language::setLocales] Locale set to: en_US.utf8
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Modules\Api\Init::initialize] initialize
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Core\Language::setLocales] Locale set to: fr_FR.utf8
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Core\Events\EventDispatcherBase::attach] Attach: SP\Providers\Log\DatabaseLogHandler
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Core\Events\EventDispatcherBase::attach] Attach: SP\Providers\Log\FileLogHandler
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Core\Events\EventDispatcherBase::attach] Attach: SP\Providers\Notification\NotificationHandler
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Bootstrap::SP\{closure}] Routing call: SP\Modules\Api\Controllers\AccountController::searchAction
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Providers\Log\FileLogHandler::updateEvent] database.query;SELECT id, userId
FROM Track
WHERE `time` >= ?
AND (ipv4 = ? OR ipv6 = ?)
AND `source` = ?;
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Providers\Log\FileLogHandler::updateEvent] database.query;SELECT id, actionId, userId, vault, `hash`, token
FROM AuthToken
WHERE actionId = ?
AND token = ? LIMIT 1;
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Providers\Log\FileLogHandler::updateEvent] database.query;SELECT U.id,
U.name,
U.userGroupId,
UG.name AS userGroupName,
U.login,
U.ssoLogin,
U.email,
U.notes,
U.loginCount,
U.userProfileId,
U.lastLogin,
U.lastUpdate,
U.lastUpdateMPass,
U.preferences,
U.pass,
U.hashSalt,
U.mPass,
U.mKey,
U.isAdminApp,
U.isAdminAcc,
U.isLdap,
U.isDisabled,
U.isChangePass,
U.isChangedPass,
U.isMigrate
FROM User U
INNER JOIN UserGroup UG ON U.userGroupId = UG.id
WHERE U.id = ? LIMIT 1;
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Providers\Log\FileLogHandler::updateEvent] database.query;SELECT id, `name`, `profile` FROM UserProfile WHERE id = ? LIMIT 1;
[16-Aug-2018 11:05:59 Europe/Paris] [DEBUG] [SP\Providers\Log\FileLogHandler::updateEvent] database.query;SELECT DISTINCT Account.* FROM account_search_v Account WHERE (((Account.isPrivate IS NULL OR Account.isPrivate = 0 OR (Account.isPrivate = 1 AND Account.userId = ?)) AND (Account.isPrivateGroup IS NULL OR Account.isPrivateGroup = 0 OR (Account.isPrivateGroup = 1 AND Account.userGroupId = ?)))) AND ((Account.name LIKE ? OR Account.login LIKE ? OR Account.url LIKE ? OR Account.notes LIKE ?)) ORDER BY Account.clientName, Account.name ASC LIMIT ?, ?;
No return in CLI.
A few notes concerning this matter:
We will try reforming template to https://server-sys.net/api.php and see if it changes anything (Which I think wont because in the logs the requests reaches the server).
Hello @GGOUSSEAUD
This is a good testing work, let me review it next week, when go back from holidays.
Regards
Hayo @nuxsmin , good news, we've updated our servers and it's working now.
We don't know exactly which one caused it but we've done it! ;)
Here is our update jump : 8a7a51e -> 330e85f
Closing this issue.
Hi @GGOUSSEAUD that sounds great.
I've done some improvements in API (including new options for account searching) and the most important stuff, functional tests, so now I can completely test all the API methods in a click!
Thanks for the feedback!
Most helpful comment
OT: Wow...I've just noticed this is the issue number 1000!!...unfortunately, there are no gifts here ;)