mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 17:25:20 +00:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8887e7318 | ||
|
|
63918bfebc | ||
|
|
b30a30ecce |
@@ -33,7 +33,6 @@
|
||||
0481A3472E6D869F00FC845E /* TorURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0481A3442E6D869F00FC845E /* TorURLSession.swift */; };
|
||||
0481A3482E6D869F00FC845E /* TorManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0481A3432E6D869F00FC845E /* TorManager.swift */; };
|
||||
0481A3492E6D869F00FC845E /* TorURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0481A3442E6D869F00FC845E /* TorURLSession.swift */; };
|
||||
|
||||
0481A35B2E6D9BEF00FC845E /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0481A35A2E6D9BEF00FC845E /* libz.tbd */; };
|
||||
0481A35D2E6DA18600FC845E /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0481A35C2E6DA18600FC845E /* libz.tbd */; };
|
||||
0481A3902E734CAE00FC845E /* CommandProcessorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0481A38F2E734CAE00FC845E /* CommandProcessorTests.swift */; };
|
||||
@@ -383,7 +382,6 @@
|
||||
0481A39F2E744D6300FC845E /* tor-nolzma.xcframework */,
|
||||
0481A35A2E6D9BEF00FC845E /* libz.tbd */,
|
||||
0481A35C2E6DA18600FC845E /* libz.tbd */,
|
||||
|
||||
);
|
||||
path = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@@ -815,7 +813,10 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
<<<<<<< Updated upstream
|
||||
|
||||
=======
|
||||
>>>>>>> Stashed changes
|
||||
7DD72D928FF9DD3CA81B46B0 /* Assets.xcassets in Resources */,
|
||||
E0A1B2C3D4E5F6012345678D /* relays/online_relays_gps.csv in Resources */,
|
||||
);
|
||||
|
||||
@@ -86,6 +86,38 @@ final class SecureLogger {
|
||||
return level.order >= minimumLevel.order
|
||||
}
|
||||
|
||||
// MARK: - In-memory debug buffer (DEBUG builds only)
|
||||
#if DEBUG
|
||||
private static let logBufferQueue = DispatchQueue(label: "chat.bitchat.securelogger.buffer")
|
||||
private static var logBuffer: [String] = []
|
||||
private static let logBufferCap: Int = 2000
|
||||
|
||||
/// Append a sanitized line to the in-memory debug buffer
|
||||
private static func record(_ line: String) {
|
||||
logBufferQueue.async {
|
||||
logBuffer.append(line)
|
||||
if logBuffer.count > logBufferCap {
|
||||
logBuffer.removeFirst(logBuffer.count - logBufferCap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the current logs as an array (oldest first)
|
||||
static func getLogs() -> [String] {
|
||||
return logBufferQueue.sync { logBuffer }
|
||||
}
|
||||
|
||||
/// Get the current logs as a single string
|
||||
static func getLogText() -> String {
|
||||
return getLogs().joined(separator: "\n")
|
||||
}
|
||||
|
||||
/// Clear the in-memory debug buffer
|
||||
static func clearLogs() {
|
||||
logBufferQueue.async { logBuffer.removeAll(keepingCapacity: false) }
|
||||
}
|
||||
#endif
|
||||
|
||||
// MARK: - Security Event Types
|
||||
|
||||
enum SecurityEvent {
|
||||
@@ -159,7 +191,9 @@ final class SecureLogger {
|
||||
let errorDesc = sanitize(error.localizedDescription)
|
||||
|
||||
#if DEBUG
|
||||
os_log("%{public}@ Error in %{public}@: %{public}@", log: category, type: .error, location, sanitized, errorDesc)
|
||||
let line = "\(location) Error: \(sanitized) — \(errorDesc)"
|
||||
os_log("%{public}@", log: category, type: .error, line)
|
||||
record(line)
|
||||
#else
|
||||
os_log("%{private}@ Error in %{private}@: %{private}@", log: category, type: .error, location, sanitized, errorDesc)
|
||||
#endif
|
||||
@@ -203,6 +237,7 @@ private extension SecureLogger {
|
||||
|
||||
#if DEBUG
|
||||
os_log("%{public}@", log: category, type: level.osLogType, sanitized)
|
||||
record(sanitized)
|
||||
#else
|
||||
// In release builds, only log non-debug messages
|
||||
if level != .debug {
|
||||
@@ -220,6 +255,7 @@ private extension SecureLogger {
|
||||
|
||||
#if DEBUG
|
||||
os_log("%{public}@", log: .security, type: level.osLogType, message)
|
||||
record(message)
|
||||
#else
|
||||
// In release, use private logging to prevent sensitive data exposure
|
||||
os_log("%{private}@", log: .security, type: level.osLogType, message)
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import SwiftUI
|
||||
#if os(iOS)
|
||||
import UIKit
|
||||
#elseif os(macOS)
|
||||
import AppKit
|
||||
#endif
|
||||
|
||||
struct AppInfoView: View {
|
||||
@Environment(\.dismiss) var dismiss
|
||||
@@ -191,12 +196,77 @@ struct AppInfoView: View {
|
||||
.background(Color.red.opacity(0.1))
|
||||
.cornerRadius(8)
|
||||
|
||||
.padding(.top)
|
||||
#if DEBUG
|
||||
// Debug section (visible only in Debug builds)
|
||||
DebugLogsSection(textColor: textColor, secondaryTextColor: secondaryTextColor)
|
||||
.padding(.top)
|
||||
#endif
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
private struct DebugLogsSection: View {
|
||||
let textColor: Color
|
||||
let secondaryTextColor: Color
|
||||
@State private var logsText: String = SecureLogger.getLogText()
|
||||
private let timer = Timer.publish(every: 1.0, on: .main, in: .common).autoconnect()
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
SectionHeader("DEBUG")
|
||||
|
||||
HStack(spacing: 12) {
|
||||
Button {
|
||||
copyToPasteboard(logsText)
|
||||
} label: {
|
||||
Text("copy logs")
|
||||
.font(.system(size: 14, design: .monospaced))
|
||||
.foregroundColor(textColor)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
|
||||
Button {
|
||||
SecureLogger.clearLogs()
|
||||
logsText = ""
|
||||
} label: {
|
||||
Text("clear logs")
|
||||
.font(.system(size: 14, design: .monospaced))
|
||||
.foregroundColor(textColor)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
Text(logsText.isEmpty ? "(no logs)" : logsText)
|
||||
.font(.system(size: 12, design: .monospaced))
|
||||
.foregroundColor(secondaryTextColor)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.textSelection(.enabled)
|
||||
.padding(8)
|
||||
}
|
||||
.frame(minHeight: 180)
|
||||
.background(secondaryTextColor.opacity(0.08))
|
||||
.cornerRadius(8)
|
||||
}
|
||||
.onReceive(timer) { _ in
|
||||
logsText = SecureLogger.getLogText()
|
||||
}
|
||||
}
|
||||
|
||||
private func copyToPasteboard(_ text: String) {
|
||||
#if os(iOS)
|
||||
UIPasteboard.general.string = text
|
||||
#elseif os(macOS)
|
||||
let pb = NSPasteboard.general
|
||||
pb.clearContents()
|
||||
pb.setString(text, forType: .string)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
struct SectionHeader: View {
|
||||
let title: String
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
|
||||
Reference in New Issue
Block a user