row editing
This commit is contained in:
@@ -221,8 +221,8 @@
|
|||||||
ENABLE_APP_SANDBOX = NO;
|
ENABLE_APP_SANDBOX = NO;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "DBSyn";
|
INFOPLIST_KEY_CFBundleDisplayName = "DBSyn";
|
||||||
MARKETING_VERSION = 1.0.3;
|
MARKETING_VERSION = 1.0.4;
|
||||||
CURRENT_PROJECT_VERSION = 76;
|
CURRENT_PROJECT_VERSION = 77;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2026 ABSDEV. All rights reserved.";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2026 ABSDEV. All rights reserved.";
|
||||||
@@ -244,8 +244,8 @@
|
|||||||
ENABLE_APP_SANDBOX = NO;
|
ENABLE_APP_SANDBOX = NO;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "DBSyn";
|
INFOPLIST_KEY_CFBundleDisplayName = "DBSyn";
|
||||||
MARKETING_VERSION = 1.0.3;
|
MARKETING_VERSION = 1.0.4;
|
||||||
CURRENT_PROJECT_VERSION = 76;
|
CURRENT_PROJECT_VERSION = 77;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2026 ABSDEV. All rights reserved.";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2026 ABSDEV. All rights reserved.";
|
||||||
|
|||||||
+24
-6
@@ -7909,11 +7909,26 @@ private enum LaravelBcryptService {
|
|||||||
return String(result.prefix(length))
|
return String(result.prefix(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func resolvedPHPPath(_ preferred: String = "") -> String? {
|
||||||
|
let fm = FileManager.default
|
||||||
|
let root = "/Applications/ServBay/package/php"
|
||||||
|
let versions = (try? fm.contentsOfDirectory(atPath: root)) ?? []
|
||||||
|
let servBay = versions.sorted { $0.compare($1, options: .numeric) == .orderedDescending }
|
||||||
|
.map { version -> String in
|
||||||
|
let base = "\(root)/\(version)"
|
||||||
|
let builds = (try? fm.contentsOfDirectory(atPath: base)) ?? []
|
||||||
|
let latest = builds.sorted { $0.compare($1, options: .numeric) == .orderedDescending }
|
||||||
|
return latest.first(where: { fm.isExecutableFile(atPath: "\(base)/\($0)/bin/php") })
|
||||||
|
.map { "\(base)/\($0)/bin/php" } ?? ""
|
||||||
|
}
|
||||||
|
let candidates = [preferred.trimmingCharacters(in: .whitespacesAndNewlines),
|
||||||
|
"/Applications/ServBay/script/alias/php"] + servBay +
|
||||||
|
["/opt/homebrew/bin/php", "/usr/local/bin/php", "/usr/bin/php"]
|
||||||
|
return candidates.first(where: { !$0.isEmpty && $0.hasPrefix("/") && fm.isExecutableFile(atPath: $0) })
|
||||||
|
}
|
||||||
|
|
||||||
static func hash(_ plaintext: String, phpPath: String) throws -> String {
|
static func hash(_ plaintext: String, phpPath: String) throws -> String {
|
||||||
let candidates = [phpPath, "/opt/homebrew/bin/php", "/usr/local/bin/php", "/usr/bin/php"]
|
guard let executable = resolvedPHPPath(phpPath) else { throw HashError.noPHP }
|
||||||
guard let executable = candidates.first(where: {
|
|
||||||
!$0.isEmpty && $0.hasPrefix("/") && FileManager.default.isExecutableFile(atPath: $0)
|
|
||||||
}) else { throw HashError.noPHP }
|
|
||||||
|
|
||||||
let process = Process()
|
let process = Process()
|
||||||
process.executableURL = URL(fileURLWithPath: executable)
|
process.executableURL = URL(fileURLWithPath: executable)
|
||||||
@@ -7946,7 +7961,7 @@ private struct DBSynLaravelPasswordGenerator: View {
|
|||||||
let onUseHash: (String) -> Void
|
let onUseHash: (String) -> Void
|
||||||
@State private var plaintext = ""
|
@State private var plaintext = ""
|
||||||
@State private var hashed = ""
|
@State private var hashed = ""
|
||||||
@State private var phpPath = ""
|
@AppStorage("DBSyn.LaravelPHPPath") private var phpPath = ""
|
||||||
@State private var showPassword = false
|
@State private var showPassword = false
|
||||||
@State private var busy = false
|
@State private var busy = false
|
||||||
@State private var errorText: String?
|
@State private var errorText: String?
|
||||||
@@ -7974,9 +7989,12 @@ private struct DBSynLaravelPasswordGenerator: View {
|
|||||||
HStack {
|
HStack {
|
||||||
TextField("PHP executable path (optional)", text: $phpPath)
|
TextField("PHP executable path (optional)", text: $phpPath)
|
||||||
.textFieldStyle(.roundedBorder)
|
.textFieldStyle(.roundedBorder)
|
||||||
Text("Uses Homebrew PHP automatically when available")
|
Text("Detects ServBay and Homebrew PHP automatically")
|
||||||
.font(.caption).foregroundStyle(.secondary)
|
.font(.caption).foregroundStyle(.secondary)
|
||||||
}
|
}
|
||||||
|
Text("PHP: " + (LaravelBcryptService.resolvedPHPPath(phpPath) ?? "Not found"))
|
||||||
|
.font(.caption.monospaced()).foregroundStyle(.secondary)
|
||||||
|
.textSelection(.enabled)
|
||||||
HStack {
|
HStack {
|
||||||
Button(busy ? "Hashing…" : "Generate bcrypt Hash") { generateHash() }
|
Button(busy ? "Hashing…" : "Generate bcrypt Hash") { generateHash() }
|
||||||
.disabled(plaintext.isEmpty || busy)
|
.disabled(plaintext.isEmpty || busy)
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# DBSyn 1.0.4 (Build 77)
|
||||||
|
|
||||||
|
- Automatically discovers ServBay PHP installations, preferring the highest installed PHP version.
|
||||||
|
- Falls back to ServBay alias, Homebrew and standard PHP paths.
|
||||||
|
- Remembers an optional manually specified PHP executable between launches.
|
||||||
|
- Shows the resolved executable in the Laravel Password Generator.
|
||||||
|
- Retains stdin-based bcrypt generation and the existing Use Hash in Row workflow.
|
||||||
|
|
||||||
|
Source patch only; Xcode build and macOS runtime validation have not been performed.
|
||||||
Reference in New Issue
Block a user