Skip to content

Commit

Permalink
fix(bundler): team ID is now required for notarytool via app password (
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog authored Oct 6, 2023
1 parent cdd5516 commit 40d3400
Show file tree
Hide file tree
Showing 12 changed files with 54 additions and 42 deletions.
5 changes: 5 additions & 0 deletions .changes/notarytool-team-id-required.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri-bundler": patch:bug
---

The `APPLE_TEAM_ID` environment variable is now required for notarization authentication via Apple ID and app-specific password.
3 changes: 2 additions & 1 deletion core/tauri-runtime-wry/src/global_shortcut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::{
collections::HashMap,
error::Error as StdError,
fmt,
rc::Rc,
sync::{
mpsc::{channel, Sender},
Arc, Mutex,
Expand Down Expand Up @@ -138,7 +139,7 @@ impl<T: UserEvent> GlobalShortcutManager for GlobalShortcutManagerHandle<T> {

pub fn handle_global_shortcut_message(
message: GlobalShortcutMessage,
global_shortcut_manager: &Arc<Mutex<WryShortcutManager>>,
global_shortcut_manager: &Rc<Mutex<WryShortcutManager>>,
) {
match message {
GlobalShortcutMessage::IsRegistered(accelerator, tx) => tx
Expand Down
8 changes: 4 additions & 4 deletions core/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ pub struct DispatcherMainThreadContext<T: UserEvent> {
pub window_target: EventLoopWindowTarget<Message<T>>,
pub web_context: WebContextStore,
#[cfg(all(desktop, feature = "global-shortcut"))]
pub global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
pub global_shortcut_manager: Rc<Mutex<WryShortcutManager>>,
#[cfg(feature = "clipboard")]
pub clipboard_manager: Arc<Mutex<Clipboard>>,
pub windows: Rc<RefCell<HashMap<WebviewId, WindowWrapper>>>,
Expand Down Expand Up @@ -1937,7 +1937,7 @@ impl<T: UserEvent> Wry<T> {
let web_context = WebContextStore::default();

#[cfg(all(desktop, feature = "global-shortcut"))]
let global_shortcut_manager = Arc::new(Mutex::new(WryShortcutManager::new(&event_loop)));
let global_shortcut_manager = Rc::new(Mutex::new(WryShortcutManager::new(&event_loop)));

#[cfg(feature = "clipboard")]
let clipboard_manager = Arc::new(Mutex::new(Clipboard::new()));
Expand Down Expand Up @@ -2307,7 +2307,7 @@ pub struct EventLoopIterationContext<'a, T: UserEvent> {
pub webview_id_map: WebviewIdStore,
pub windows: Rc<RefCell<HashMap<WebviewId, WindowWrapper>>>,
#[cfg(all(desktop, feature = "global-shortcut"))]
pub global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
pub global_shortcut_manager: Rc<Mutex<WryShortcutManager>>,
#[cfg(all(desktop, feature = "global-shortcut"))]
pub global_shortcut_manager_handle: &'a GlobalShortcutManagerHandle<T>,
#[cfg(feature = "clipboard")]
Expand All @@ -2320,7 +2320,7 @@ struct UserMessageContext {
windows: Rc<RefCell<HashMap<WebviewId, WindowWrapper>>>,
webview_id_map: WebviewIdStore,
#[cfg(all(desktop, feature = "global-shortcut"))]
global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
global_shortcut_manager: Rc<Mutex<WryShortcutManager>>,
#[cfg(feature = "clipboard")]
clipboard_manager: Arc<Mutex<Clipboard>>,
#[cfg(all(desktop, feature = "system-tray"))]
Expand Down
2 changes: 1 addition & 1 deletion core/tauri/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ fn replace_csp_nonce(
.into_iter()
.map(|n| format!("'nonce-{n}'"))
.collect::<Vec<String>>();
let sources = csp.entry(directive.into()).or_insert_with(Default::default);
let sources = csp.entry(directive.into()).or_default();
let self_source = "'self'".to_string();
if !sources.contains(&self_source) {
sources.push(self_source);
Expand Down
2 changes: 1 addition & 1 deletion core/tauri/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1630,7 +1630,7 @@ impl<R: Runtime> Window<R> {
window_label,
event,
})
.or_insert_with(Default::default)
.or_default()
.insert(id);
}

Expand Down
2 changes: 1 addition & 1 deletion examples/api/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 4 additions & 6 deletions tooling/bundler/src/bundle/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,8 @@ impl CommandExt for Command {
let mut lines = stdout_lines_.lock().unwrap();
loop {
buf.clear();
match tauri_utils::io::read_line(&mut stdout, &mut buf) {
Ok(s) if s == 0 => break,
_ => (),
if let Ok(0) = tauri_utils::io::read_line(&mut stdout, &mut buf) {
break;
}
debug!(action = "stdout"; "{}", String::from_utf8_lossy(&buf));
lines.extend(buf.clone());
Expand All @@ -187,9 +186,8 @@ impl CommandExt for Command {
let mut lines = stderr_lines_.lock().unwrap();
loop {
buf.clear();
match tauri_utils::io::read_line(&mut stderr, &mut buf) {
Ok(s) if s == 0 => break,
_ => (),
if let Ok(0) = tauri_utils::io::read_line(&mut stderr, &mut buf) {
break;
}
debug!(action = "stderr"; "{}", String::from_utf8_lossy(&buf));
lines.extend(buf.clone());
Expand Down
8 changes: 6 additions & 2 deletions tooling/bundler/src/bundle/macos/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
use super::{
super::common::{self, CommandExt},
icon::create_icns_file,
sign::{notarize, notarize_auth, sign, SignTarget},
sign::{notarize, notarize_auth, sign, NotarizeAuthError, SignTarget},
};
use crate::Settings;

Expand Down Expand Up @@ -127,7 +127,11 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
notarize(app_bundle_path.clone(), auth, settings)?;
}
Err(e) => {
warn!("skipping app notarization, {}", e.to_string());
if matches!(e, NotarizeAuthError::MissingTeamId) {
return Err(anyhow::anyhow!("{e}").into());
} else {
warn!("skipping app notarization, {}", e.to_string());
}
}
}
}
Expand Down
37 changes: 22 additions & 15 deletions tooling/bundler/src/bundle/macos/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ pub enum NotarizeAuth {
AppleId {
apple_id: OsString,
password: OsString,
team_id: Option<OsString>,
team_id: OsString,
},
ApiKey {
key: OsString,
Expand All @@ -356,17 +356,13 @@ impl NotarytoolCmdExt for Command {
apple_id,
password,
team_id,
} => {
self
.arg("--apple-id")
.arg(apple_id)
.arg("--password")
.arg(password);
if let Some(team_id) = team_id {
self.arg("--team-id").arg(team_id);
}
self
}
} => self
.arg("--apple-id")
.arg(apple_id)
.arg("--password")
.arg(password)
.arg("--team-id")
.arg(team_id),
NotarizeAuth::ApiKey {
key,
key_path,
Expand All @@ -382,17 +378,28 @@ impl NotarytoolCmdExt for Command {
}
}

pub fn notarize_auth() -> crate::Result<NotarizeAuth> {
#[derive(Debug, thiserror::Error)]
pub enum NotarizeAuthError {
#[error(
"The team ID is now required for notarization with app-specific password as authentication. Please set the `APPLE_TEAM_ID` environment variable. You can find the team ID in https://developer.apple.com/account#MembershipDetailsCard."
)]
MissingTeamId,
#[error(transparent)]
Anyhow(#[from] anyhow::Error),
}

pub fn notarize_auth() -> Result<NotarizeAuth, NotarizeAuthError> {
match (
var_os("APPLE_ID"),
var_os("APPLE_PASSWORD"),
var_os("APPLE_TEAM_ID"),
) {
(Some(apple_id), Some(password), team_id) => Ok(NotarizeAuth::AppleId {
(Some(apple_id), Some(password), Some(team_id)) => Ok(NotarizeAuth::AppleId {
apple_id,
password,
team_id,
}),
(Some(_apple_id), Some(_password), None) => Err(NotarizeAuthError::MissingTeamId),
_ => {
match (var_os("APPLE_API_KEY"), var_os("APPLE_API_ISSUER"), var("APPLE_API_KEY_PATH")) {
(Some(key), Some(issuer), Ok(key_path)) => {
Expand Down Expand Up @@ -424,7 +431,7 @@ pub fn notarize_auth() -> crate::Result<NotarizeAuth> {
Err(anyhow::anyhow!("could not find API key file. Please set the APPLE_API_KEY_PATH environment variables to the path to the {api_key_file_name:?} file").into())
}
}
_ => Err(anyhow::anyhow!("no APPLE_ID & APPLE_PASSWORD or APPLE_API_KEY & APPLE_API_ISSUER & APPLE_API_KEY_PATH environment variables found").into())
_ => Err(anyhow::anyhow!("no APPLE_ID & APPLE_PASSWORD & APPLE_TEAM_ID or APPLE_API_KEY & APPLE_API_ISSUER & APPLE_API_KEY_PATH environment variables found").into())
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions tooling/cli/ENVIRONMENT_VARIABLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ These environment variables are inputs to the CLI which may have an equivalent C
- `TAURI_KEY_PASSWORD` — The private key password, see `TAURI_PRIVATE_KEY`
- `APPLE_CERTIFICATE` — Base64 encoded of the `.p12` certificate for code signing. To get this value, run `openssl base64 -in MyCertificate.p12 -out MyCertificate-base64.txt`.
- `APPLE_CERTIFICATE_PASSWORD` — The password you used to export the certificate.
- `APPLE_ID` — The Apple ID used to notarize the application. If this environment variable is provided, `APPLE_PASSWORD` must also be set. Alternatively, `APPLE_API_KEY` and `APPLE_API_ISSUER` can be used to authenticate.
- `APPLE_ID` — The Apple ID used to notarize the application. If this environment variable is provided, `APPLE_PASSWORD` and `APPLE_TEAM_ID` must also be set. Alternatively, `APPLE_API_KEY` and `APPLE_API_ISSUER` can be used to authenticate.
- `APPLE_PASSWORD` — The Apple password used to authenticate for application notarization. Required if `APPLE_ID` is specified. An app-specific password can be used. Alternatively to entering the password in plaintext, it may also be specified using a '@keychain:' or '@env:' prefix followed by a keychain password item name or environment variable name.
- `APPLE_TEAM_ID`: Developer team ID. If your Apple ID only belongs to one team then you don’t need to supply a Team ID. However, it’s best practice to include it regardless. That way, joining another team at some point in the future won’t break your notarization workflow. To find your Team ID, go to the [Account](https://developer.apple.com/account) page on the Apple Developer website.
- `APPLE_TEAM_ID`: Developer team ID. To find your Team ID, go to the [Account](https://developer.apple.com/account) page on the Apple Developer website, and check your membership details.
- `APPLE_API_KEY` — Alternative to `APPLE_ID` and `APPLE_PASSWORD` for notarization authentication using JWT.
- See [creating API keys](https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api) for more information.
- `APPLE_API_ISSUER` — Issuer ID. Required if `APPLE_API_KEY` is specified.
Expand Down
5 changes: 2 additions & 3 deletions tooling/cli/src/interface/rust/desktop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,8 @@ fn build_dev_app<F: FnOnce(ExitStatus, ExitReason) + Send + 'static>(
let mut io_stderr = std::io::stderr();
loop {
buf.clear();
match tauri_utils::io::read_line(&mut stderr, &mut buf) {
Ok(s) if s == 0 => break,
_ => (),
if let Ok(0) = tauri_utils::io::read_line(&mut stderr, &mut buf) {
break;
}
let _ = io_stderr.write_all(&buf);
if !buf.ends_with(&[b'\r']) {
Expand Down
10 changes: 4 additions & 6 deletions tooling/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,8 @@ impl CommandExt for Command {
let mut lines = stdout_lines_.lock().unwrap();
loop {
buf.clear();
match tauri_utils::io::read_line(&mut stdout, &mut buf) {
Ok(s) if s == 0 => break,
_ => (),
if let Ok(0) = tauri_utils::io::read_line(&mut stdout, &mut buf) {
break;
}
debug!(action = "stdout"; "{}", String::from_utf8_lossy(&buf));
lines.extend(buf.clone());
Expand All @@ -248,9 +247,8 @@ impl CommandExt for Command {
let mut lines = stderr_lines_.lock().unwrap();
loop {
buf.clear();
match tauri_utils::io::read_line(&mut stderr, &mut buf) {
Ok(s) if s == 0 => break,
_ => (),
if let Ok(0) = tauri_utils::io::read_line(&mut stderr, &mut buf) {
break;
}
debug!(action = "stderr"; "{}", String::from_utf8_lossy(&buf));
lines.extend(buf.clone());
Expand Down

0 comments on commit 40d3400

Please sign in to comment.