Skip to content
This repository has been archived by the owner on Nov 4, 2020. It is now read-only.

Commit

Permalink
Bug Fixes, iOS App Instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
chandlerhuff committed Jan 8, 2018
1 parent 7e774cf commit 3d433b3
Show file tree
Hide file tree
Showing 11 changed files with 116 additions and 12 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,16 @@ First visit the Fax Server's address and register a new user account after you c
- [Advanced Users] Enabled secure (HTTPS Only) cookies in settings. This should only be done if you only access your server over a HTTPS connection and will restrict logins to HTTPS only. Note if you enable this you will not be able to sign in over an insecure (HTTP) connection to turn if off.
- [Advanced Users] Enable 2 factor authentication (TOTP) login, under Users select your user account and activate 2 factor authentication. Note there is no way to reset this if you loose your TOTP secret key.
- [Advanced Users] If you will not be receiving Nexmo SMS messages the webhook can be disabled in Fax Server settings.

### 📱 iOS App Setup

![Fax Server](https://media.bludesign.biz/fax_client.png)

- Open Clients in Fax Server and create a client with the above values.
- After creating the client copy the Client ID and Client Secret and fill them into the iOS app along with your servers URL.

<p align="center">
<a href="https://itunes.apple.com/us/app/fax-server/id1331048085?ls=1&mt=8">
<img src="https://media.bludesign.biz/appstore.svg" alt="App Store">
</a>
</p>
1 change: 1 addition & 0 deletions Resources/Views/admin.leaf
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@
</div>
<div class="card-footer">
<button type="submit" class="btn btn-sm btn-primary" name="action" value="send"><i class="fa fa-dot-circle-o"></i> Save</button>
<button type="submit" class="btn btn-sm btn-primary" name="action" value="testPush"><i class="fa fa-dot-circle-o"></i> Send Test Push</button>
</div>
</form>
</div>
Expand Down
39 changes: 39 additions & 0 deletions Resources/Views/user.leaf
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,45 @@
</div>
</form>
</div>
<div class="card">
<div class="card-header">
<i class="fa fa-align-justify"></i> Push Devices
</div>
<div class="card-block">
<table class="table table-hover table-responsive">
<thead>
<tr>
<th>Device Name</th>
<th>Updated At</th>
<th>Token</th>
</tr>
</thead>
<tbody>
#raw(tableData)
</tbody>
</table>
<ul class="pagination">
<li class="page-item">
<a class="page-link" href="#(prevPage)" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
<span class="sr-only">Previous</span>
</a>
</li>
#raw(pageData)
<li class="page-item">
<a class="page-link" href="#(nextPage)" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
<span class="sr-only">Next</span>
</a>
</li>
</ul>
</div>
<div class="card-footer">
<form class="form-signin" action="/device/testPush" method="post">
<button type="submit" class="btn btn-sm btn-success" name="action" value="testPush"><i class="fa fa-dot-circle-o"></i> Send Test Push</button>
</form>
</div>
</div>
</div>
</div>
</div>
Expand Down
3 changes: 2 additions & 1 deletion Sources/Server/Middleware/AuthenicationMiddleware.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@ extension Request {
let tokenHash = try Application.makeHash(token)
guard var accessToken = try AccessToken.collection.findOne("token" == tokenHash) else { return nil }
guard let tokenExpiration = accessToken["tokenExpires"] as? Date else { return nil }
guard let source = accessToken["source"] as? String else { return nil }
guard Date() < tokenExpiration else { return nil }
guard let userId = accessToken["userId"] as? ObjectId else { return nil }
if tokenExpiration.timeIntervalSinceReferenceDate - 432000 < Date().timeIntervalSinceReferenceDate, let objectId = accessToken.objectId {
if tokenExpiration.timeIntervalSinceReferenceDate - 432000 < Date().timeIntervalSinceReferenceDate, let objectId = accessToken.objectId, source == "cookie" {
let expirationDate = Date(timeIntervalSinceNow: AccessToken.cookieExpiresIn)
accessToken["tokenExpires"] = expirationDate
accessToken["endOfLife"] = expirationDate
Expand Down
4 changes: 4 additions & 0 deletions Sources/Server/Models/AccessToken.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ struct AccessToken {
throw ServerAbort(.unauthorized, reason: "Refresh token not found")
}
let scope = try accessToken.extract("scope") as String
let source = try accessToken.extract("source") as String
guard source == "oauth" else {
throw ServerAbort(.unauthorized, reason: "Access token is not valid")
}
let token = try String.tokenEncoded()
let tokenHash = try Application.makeHash(token)
accessToken["tokenExpires"] = Date(timeIntervalSinceNow: AccessToken.expiresIn)
Expand Down
1 change: 0 additions & 1 deletion Sources/Server/Providers/PushProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ final class PushProvider: Vapor.Provider {

static func sendPush(threadId: String, title: String, body: String, userId: ObjectId? = nil) {
let payload = Payload(title: title, body: body)
payload.threadId = threadId
do {
let devices: CollectionSlice<Document>
if let userId = userId {
Expand Down
4 changes: 4 additions & 0 deletions Sources/Server/Routes/Admin+Routes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ extension Admin {

// MARK: Update Settings
protected.post { request in
if request.data["action"]?.string == "testPush" {
PushProvider.sendPush(threadId: "test", title: "Test Notification", body: "Test Push Notification")
return Response(redirect: "/admin")
}
if let domain = try? request.data.extract("domain") as String {
guard let url = URL(string: domain), let domain = url.domain else {
throw ServerAbort(.badRequest, reason: "Domain format is invalid")
Expand Down
11 changes: 11 additions & 0 deletions Sources/Server/Routes/Device+Routes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,25 @@ extension Device {
protected.post { request in
let userId = try request.getUserId()
let deviceToken = try request.data.extract("deviceToken") as String
let deviceName = try request.data.extract("deviceName") as String
let document: Document = [
"deviceToken": deviceToken,
"deviceName": deviceName,
"updatedAt": Date(),
"userId": userId
]
try Device.collection.update("deviceToken" == deviceToken, to: document, upserting: true)

return Response(jsonStatus: .ok)
}

protected.post("testPush") { request in
let userId = try request.getUserId()
PushProvider.sendPush(threadId: "test", title: "Test Notification", body: "Test Push Notification", userId: userId)
if request.jsonResponse {
return Response(jsonStatus: .ok)
}
return Response(redirect: "/user/\(userId.hexString)")
}
}
}
15 changes: 8 additions & 7 deletions Sources/Server/Routes/Fax+Routes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ extension Fax {
}

let token = try String.token()
let fileToken = try String.token()
let fromString = request.data["from"]?.string ?? phoneNumber

var document: Document = [
Expand All @@ -191,15 +190,16 @@ extension Fax {
"senderEmail": senderEmail,
"status": "started",
"dateCreated": Date(),
"accountId": accountId
"accountId": accountId,
"direction": "outbound"
]
guard let objectId = try Fax.collection.insert(document) as? ObjectId else {
throw ServerAbort(.notFound, reason: "Error creating fax")
}

let fileDocument: Document = [
"faxObjectId": objectId,
"token": fileToken,
"token": token,
"dateCreated": Date(),
"data": Data(bytes: bytes)
]
Expand All @@ -216,7 +216,7 @@ extension Fax {
request.body = .data(try Node(node: [
"From": fromString,
"To": toString,
"MediaUrl": "\(url)/fax/file/\(objectId.hexString)/\(fileToken)",
"MediaUrl": "\(url)/fax/file/\(objectId.hexString)/\(token)",
"StatusCallback": "\(url)/fax/status/\(objectId.hexString)/\(token)"
]).formURLEncodedPlus())

Expand Down Expand Up @@ -444,6 +444,7 @@ extension Fax {
throw ServerAbort(.notFound, reason: "Account not found")
}
let authToken = try account.extract("authToken") as String
let token = try String.token()

var document: Document = [
"sid": sid,
Expand All @@ -457,7 +458,8 @@ extension Fax {
"pages": request.data["NumPages"]?.int,
"mediaUrl": request.data["MediaUrl"]?.string,
"errorCode": request.data["ErrorCode"]?.string,
"errorMessage": request.data["ErrorMessage"]?.string
"errorMessage": request.data["ErrorMessage"]?.string,
"token": token
]

guard let responseBytes = try drop.client.get("\(Constants.Twilio.faxUrl)/Faxes/\(sid)", [
Expand Down Expand Up @@ -491,11 +493,10 @@ extension Fax {
guard let bytes = response.body.bytes else {
throw ServerAbort(.notFound, reason: "No response body")
}
let fileToken = try String.token()

let fileDocument: Document = [
"faxObjectId": objectId,
"token": fileToken,
"token": token,
"dateCreated": Date(),
"data": Data(bytes: bytes)
]
Expand Down
5 changes: 2 additions & 3 deletions Sources/Server/Routes/Message+Routes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ extension Message {

let mediaUrl: String?
if let bytes = request.data["file"]?.bytes, bytes.count > 0 {
let fileToken = try String.token()
let mimeType: String
switch bytes[0] {
case 0xFF: mimeType = "image/jpeg"
Expand All @@ -153,15 +152,15 @@ extension Message {
}
let fileDocument: Document = [
"messageObjectId": objectId,
"token": fileToken,
"token": token,
"dateCreated": Date(),
"mimeType": mimeType,
"data": Data(bytes: bytes)
]
guard let fileObjectId = try MessageFile.collection.insert(fileDocument) as? ObjectId else {
throw ServerAbort(.notFound, reason: "Error creating message file")
}
mediaUrl = "\(url)/message/file/\(fileObjectId.hexString)/\(fileToken)"
mediaUrl = "\(url)/message/file/\(fileObjectId.hexString)/\(token)"
} else {
mediaUrl = nil
}
Expand Down
32 changes: 32 additions & 0 deletions Sources/Server/Routes/User+Routes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,41 @@ extension User {
if request.jsonResponse {
return try document.makeResponse()
} else {
let pageInfo = request.pageInfo
let devices = try Device.collection.find("userId" == objectId, sortedBy: ["updatedAt": .ascending], skipping: pageInfo.skip, limitedTo: pageInfo.limit, withBatchSize: pageInfo.limit)

let link = "/users/\(objectId.hexString)?"
var pages = try (devices.count() / pageInfo.limit) + 1
let startPage: Int
if pages > 7 {
let firstPage = pageInfo.page - 3
let lastPage = pageInfo.page + 2
startPage = max(pageInfo.page - 3 - (lastPage > pages ? lastPage - pages : 0), 0)
pages = min(pages, lastPage - (firstPage < 0 ? firstPage : 0))
} else {
startPage = 0
}
var pageData: String = ""
for x in startPage..<pages {
pageData.append("<li class=\"page-item\(x == pageInfo.page - 1 ? " active" : "")\"><a class=\"page-link\" href=\"\(link)page=\(x + 1)\">\(x + 1)</a></li>")
}
var tableData: String = ""
for device in devices {
let deviceName = try device.extractString("deviceName")
let lastActionDate = try device.extractDate("updatedAt")
let deviceToken = try device.extractString("deviceToken")
let string = "<tr><td>\(deviceName)</td><td>\(lastActionDate.longString)</td><td>\(deviceToken)</td></tr>"
tableData.append(string)
}

let email = try document.extract("email") as String
let totpActivated = try? document.extract("totpActivated") as Bool
return try drop.view.make("user", [
"tableData": tableData,
"pageData": pageData,
"page": pageInfo.page,
"nextPage": (pageInfo.page + 1 > pages.count ? "#" : "/\(link)page=\(pageInfo.page + 1)"),
"prevPage": (pageInfo.page - 1 <= 0 ? "#" : "\(link)page=\(pageInfo.page - 1)"),
"userId": objectId.hexString,
"email": email,
"totpActivated": totpActivated ?? false
Expand Down

0 comments on commit 3d433b3

Please sign in to comment.