|
3 | 3 |
|
4 | 4 | import structlog |
5 | 5 | from jinja2.sandbox import SandboxedEnvironment |
| 6 | +from onepassword import ItemFieldType |
6 | 7 | from onepassword.client import Client as OnePasswordClient |
7 | 8 |
|
8 | 9 | from skyvern.config import settings |
@@ -452,24 +453,61 @@ async def register_onepassword_credential_parameter_value( |
452 | 453 | "context": "These values are placeholders. When you type this in, the real value gets inserted (For security reasons)", |
453 | 454 | } |
454 | 455 |
|
455 | | - # Process all fields |
| 456 | + # Process all fields generically so it covers passwords and credit cards |
456 | 457 | for field in item.fields: |
457 | | - if field.value is None: |
| 458 | + if not field.value or field.field_type == ItemFieldType.UNSUPPORTED: |
458 | 459 | continue |
459 | | - random_secret_id = self.generate_random_secret_id() |
| 460 | + |
| 461 | + # ignore irrelevant fields to avoid confusing AI |
| 462 | + if field.id in ["validFrom", "interest", "issuenumber"]: |
| 463 | + continue |
| 464 | + |
460 | 465 | field_type = field.field_type.value.lower() |
461 | 466 | if field_type == "totp": |
| 467 | + random_secret_id = self.generate_random_secret_id() |
462 | 468 | totp_secret_id = f"{random_secret_id}_totp" |
463 | 469 | self.secrets[totp_secret_id] = OnePasswordConstants.TOTP |
464 | 470 | totp_secret_value = self.totp_secret_value_key(totp_secret_id) |
465 | 471 | self.secrets[totp_secret_value] = parse_totp_secret(field.value) |
466 | 472 | self.values[parameter.key]["totp"] = totp_secret_id |
| 473 | + elif field.title and field.title.lower() in ["expire date", "expiry date", "expiration date"]: |
| 474 | + parts = [part.strip() for part in field.value.strip().split("/")] |
| 475 | + |
| 476 | + if len(parts) == 2: |
| 477 | + month, year_part = parts |
| 478 | + month = month.zfill(2) # ensure '5' becomes '05' |
| 479 | + |
| 480 | + if len(year_part) == 4: |
| 481 | + year = year_part[2:] # 2025 -> 25 |
| 482 | + else: |
| 483 | + year = year_part |
| 484 | + |
| 485 | + self._add_secret_parameter_value(parameter, "card_exp_month", month) |
| 486 | + self._add_secret_parameter_value(parameter, "card_exp_year", year) |
| 487 | + if len(year) == 2: |
| 488 | + self._add_secret_parameter_value(parameter, "card_exp_mmyy", f"{month}/{year}") |
| 489 | + self._add_secret_parameter_value(parameter, "card_exp_mmyyyy", f"{month}/20{year}") |
| 490 | + else: |
| 491 | + # store the 1password-provided value additionally |
| 492 | + self._add_secret_parameter_value(parameter, "card_exp", field.value) |
| 493 | + else: |
| 494 | + # fallback on the 1password-provided value |
| 495 | + self._add_secret_parameter_value(parameter, "card_exp", field.value) |
467 | 496 | else: |
468 | | - # this will be the username or password or other field |
469 | | - key = field.id.replace(" ", "_") |
470 | | - secret_id = f"{random_secret_id}_{key}" |
471 | | - self.secrets[secret_id] = field.value |
472 | | - self.values[parameter.key][key] = secret_id |
| 497 | + # using more descriptive keys than 1password provides by default |
| 498 | + if field.id == "ccnum": |
| 499 | + self._add_secret_parameter_value(parameter, "card_number", field.value) |
| 500 | + elif field.id == "cardholder": |
| 501 | + self._add_secret_parameter_value(parameter, "card_holder_name", field.value) |
| 502 | + elif field.id == "cvv": |
| 503 | + self._add_secret_parameter_value(parameter, "card_cvv", field.value) |
| 504 | + else: |
| 505 | + # this will be the username, password or other fields |
| 506 | + self._add_secret_parameter_value(parameter, field.id.replace(" ", "_"), field.value) |
| 507 | + |
| 508 | + # Secure Note support |
| 509 | + if item.notes: |
| 510 | + self._add_secret_parameter_value(parameter, "notes", item.notes) |
473 | 511 |
|
474 | 512 | async def register_bitwarden_login_credential_parameter_value( |
475 | 513 | self, |
@@ -981,6 +1019,15 @@ async def _get_azure_vault_client_for_organization(organization: Organization) - |
981 | 1019 | azure_vault_client = AsyncAzureVaultClient.create_default() |
982 | 1020 | return azure_vault_client |
983 | 1021 |
|
| 1022 | + def _add_secret_parameter_value(self, parameter: Parameter, key: str, value: str) -> None: |
| 1023 | + if parameter.key not in self.values: |
| 1024 | + raise ValueError(f"{parameter.key} is missing") |
| 1025 | + |
| 1026 | + random_secret_id = self.generate_random_secret_id() |
| 1027 | + secret_id = f"{random_secret_id}_{key}" |
| 1028 | + self.secrets[secret_id] = value |
| 1029 | + self.values[parameter.key][key] = secret_id |
| 1030 | + |
984 | 1031 |
|
985 | 1032 | class WorkflowContextManager: |
986 | 1033 | aws_client: AsyncAWSClient |
|
0 commit comments