Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
bc8e809
feat: update azure workflow process to make pulumi first-class for ne…
tahminator Jul 8, 2026
103d154
chore: remove userAdministrator from most Azure users (this allow (#203)
tahminator Jul 9, 2026
79dd8cf
chore: remove globalReader from Kevin Ma (globalReader is globalAdmin…
tahminator Jul 9, 2026
867dead
chore: add angela yu as azure user (#205)
tahminator Jul 9, 2026
6eb4700
chore: add nancy huang to azure (#207)
tahminator Jul 9, 2026
5854222
fix: update azure secret credentials (as well as add the cmd that sho…
tahminator Jul 11, 2026
efbcc2b
chore: add `just auth` and `just re-auth` (#209)
tahminator Jul 11, 2026
775f35a
chore: remove newUser from angela (#206)
tahminator Jul 11, 2026
9ed64b1
feat: support adding apps to main branch bypass as well as teams (#211)
tahminator Jul 12, 2026
4527ee6
feat: allow patAgent to bypass main branch protections to merge updat…
tahminator Jul 12, 2026
1454c08
chore: explicitly add PULUMI_BACKEND_URL so that it knows exactly wha…
tahminator Jul 23, 2026
595d65d
add grafana-all-ro-sa (will be used as a datasource in grafana) (#219)
tahminator Jul 26, 2026
c2fdf9d
Secrets: Added Digital Ocean DNS PAT (#220)
arklian Jul 26, 2026
fd675d4
add mainBranchRequiredReviewers to all repositories (#216)
tahminator Jul 26, 2026
9677da0
delete CODEOWNERS (#217)
tahminator Jul 26, 2026
07cc9c0
add ryan (spiffyy99) to infra & cicd team (#224)
tahminator Jul 28, 2026
4efccef
chore: remove newUser from nancy (#208)
tahminator Jul 31, 2026
91d0b32
chore: add comment indicating how to unblock CI when azure creds are …
tahminator Jul 31, 2026
f5a71f0
TAN-36: encrypt codebloom.yaml (#226)
naanci Jul 31, 2026
b14b200
Update DigitalOcean DNS PAT (#227)
tahminator Aug 1, 2026
fe29bad
Update tahminator's membership type on codebloom team to maintainer (…
tahminator Aug 3, 2026
af6f3ca
user: onboarded kelly lin (#230)
Arshadul-Monir Aug 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/scripts/src/pulumi/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const { prId } = await yargs(hideBin(process.argv))
export async function main() {
const envClient = EnvClient.create(EnvClientStrategy.SOPS);
const {
azurePulumiLocation,
pulumiBackendUrl,
githubAppAppId,
githubAppInstallationId,
githubAppPrivateKey,
Expand All @@ -46,7 +46,7 @@ export async function main() {
stackName: "main",
workDir: ".",
envs: {
PULUMI_BACKEND_URL: azurePulumiLocation,
PULUMI_BACKEND_URL: pulumiBackendUrl,
...env,
},
});
Expand Down Expand Up @@ -92,10 +92,10 @@ ${res.stdout}
}

function parseCiEnv(ciEnv: Record<string, string>) {
const azurePulumiLocation = (() => {
const v = ciEnv["AZURE_PULUMI_LOCATION"];
const pulumiBackendUrl = (() => {
const v = ciEnv["PULUMI_BACKEND_URL"];
if (!v) {
throw new Error("Missing AZURE_PULUMI_LOCATION from .env.ci");
throw new Error("Missing PULUMI_BACKEND_URL from .env.ci");
}
return v;
})();
Expand Down Expand Up @@ -125,7 +125,7 @@ function parseCiEnv(ciEnv: Record<string, string>) {
})();

return {
azurePulumiLocation,
pulumiBackendUrl,
githubAppAppId,
githubAppInstallationId,
githubAppPrivateKey,
Expand Down
12 changes: 6 additions & 6 deletions .github/scripts/src/pulumi/refresh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import _ from "lodash";

export async function main() {
const envClient = EnvClient.create(EnvClientStrategy.SOPS);
const { azurePulumiLocation, env } = parseCiEnv(
const { pulumiBackendUrl, env } = parseCiEnv(
_.merge(
await envClient.readFromEnv("secrets.yaml"),
await envClient.readFromEnv("secrets.administrator.yaml"),
Expand All @@ -20,7 +20,7 @@ export async function main() {
stackName: "main",
workDir: ".",
envs: {
PULUMI_BACKEND_URL: azurePulumiLocation,
PULUMI_BACKEND_URL: pulumiBackendUrl,
...env,
},
});
Expand All @@ -42,16 +42,16 @@ export async function main() {
}

function parseCiEnv(ciEnv: Record<string, string>) {
const azurePulumiLocation = (() => {
const v = ciEnv["AZURE_PULUMI_LOCATION"];
const pulumiBackendUrl = (() => {
const v = ciEnv["PULUMI_BACKEND_URL"];
if (!v) {
throw new Error("Missing AZURE_PULUMI_LOCATION from .env.ci");
throw new Error("Missing PULUMI_BACKEND_URL from .env.ci");
}
return v;
})();

return {
azurePulumiLocation,
pulumiBackendUrl,
env: ciEnv,
};
}
Expand Down
12 changes: 6 additions & 6 deletions .github/scripts/src/pulumi/up.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import _ from "lodash";

export async function main() {
const envClient = EnvClient.create(EnvClientStrategy.SOPS);
const { azurePulumiLocation, env } = parseCiEnv(
const { pulumiBackendUrl, env } = parseCiEnv(
_.merge(
await envClient.readFromEnv("secrets.yaml"),
await envClient.readFromEnv("secrets.administrator.yaml"),
Expand All @@ -20,7 +20,7 @@ export async function main() {
stackName: "main",
workDir: ".",
envs: {
PULUMI_BACKEND_URL: azurePulumiLocation,
PULUMI_BACKEND_URL: pulumiBackendUrl,
...env,
},
});
Expand All @@ -42,16 +42,16 @@ export async function main() {
}

function parseCiEnv(ciEnv: Record<string, string>) {
const azurePulumiLocation = (() => {
const v = ciEnv["AZURE_PULUMI_LOCATION"];
const pulumiBackendUrl = (() => {
const v = ciEnv["PULUMI_BACKEND_URL"];
if (!v) {
throw new Error("Missing AZURE_PULUMI_LOCATION from .env.ci");
throw new Error("Missing PULUMI_BACKEND_URL from .env.ci");
}
return v;
})();

return {
azurePulumiLocation,
pulumiBackendUrl,
env: ciEnv,
};
}
Expand Down
5 changes: 0 additions & 5 deletions CODEOWNERS

This file was deleted.

14 changes: 14 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
### Azure cmds

# logout and authenticate again
re-auth:
az logout && just auth

# authenticate
auth:
just install-pre-scripts && az login

### Core Commands

# Initial setup command
Expand All @@ -11,6 +21,10 @@ init-pulumi *args:
preview *args:
sops exec-env secrets.yaml "sops exec-env secrets.administrator.yaml \"pulumi preview {{ args }}\""

# Print the initial password Pulumi generated for a newly-created Azure user, keyed by their full email.
get-init-pwd fullEmail:
sops exec-env secrets.yaml "pulumi stack output azureInitPwsPlaintext --show-secrets --json | jq -er --arg e '{{ fullEmail }}' '.[\$e]'"


### Secret management
# sops is a library that handles the encryption and decryption of files (primarily used for secrets).
Expand Down
3 changes: 3 additions & 0 deletions bun.lock

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@pulumi/github": "^6.12.2",
"@pulumi/postgresql": "^3.16.3",
"@pulumi/pulumi": "^3.230.0",
"@pulumi/random": "^4.21.0",
"@tahminator/pipeline": "^1.0.63",
"lodash": "^4.18.1"
}
Expand Down
15 changes: 9 additions & 6 deletions secrets.administrator.yaml
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
ARM_CLIENT_ID: ENC[AES256_GCM,data:qbcZ5yNddBGlbC/TlDc0BoQiz4SDpNaoTzldrbsnXClHzfHW,iv:/YAAPO0sYtjQsLIqCtY087+E9hPdDqK+aOWRDz0Srug=,tag:KZxyGpyeec9BL+pbSlqHkQ==,type:str]
ARM_CLIENT_SECRET: ENC[AES256_GCM,data:sCvNWJ5vt6HT4nOja03B5INpt2Hvm7KaJY8A5Bm7a4DBXbZZbGdvig==,iv:MHNxA4/Hus1TclqsTsrHYfxNDT6gkqpawwqO941po8Q=,tag:5U3B26ufzCClfuOQvdkq1w==,type:str]
#ENC[AES256_GCM,data:BH8gEurU+rmXUesa9l/FMAY8Gl2ZcVmu2UWfF9KlkHATYv3WWV7rttkUUERKrtKWdqJOYzpmlbb3M0CY/CcH7q4YWNlbZC0qjYI1iiAvYCSCuyvDDaAdabRFw4TN3tnW0Q==,iv:6p9UliuKaba6/0f8VjsxjPCcnsznDrkhHW8etHs6500=,tag:ZwxyiOskFaUTkAnX4DtbSw==,type:comment]
#ENC[AES256_GCM,data:wZT3oJBwFONQf2COI+DYwGnmDrp2w8DnITAZtzz83Jh2sk/9HnK97nHOYa4ApSuzs1Yd+7qNAgCU/Jh7eSKe3BQ8lJr9Vx5gR91PkDTHao91f+d3AHf1ktx7aQjQvUj3ttY=,iv:wiUPcQhEDfI2e4tG6l/2nWoGFix0ihldFgNZl9Vxfic=,tag:jSFVNMD7qpYssV+zR45sQQ==,type:comment]
ARM_CLIENT_SECRET: ENC[AES256_GCM,data:X6Ll4sHd5Ycj+A4dPNDjQpL99ewP+61TIAt68yNo3kcRPqDYsOi4vw==,iv:WSl3/UzBLvC94q+OlsvD6iY6pSI5lls2y2p9POD6ZSM=,tag:OpGnj5eXhZh1gy/7n9TFwA==,type:str]
ARM_TENANT_ID: ENC[AES256_GCM,data:96BqORRYTbL8HApe+v7ZRgnXvr7WHoASttvyCaeOCTJsuQPG,iv:EO++192dYNcjU83sEdvdTpqF7dfUZskJmLAMkioowXA=,tag:vO14lQdLkKVQIbcaCQ93Nw==,type:str]
ARM_SUBSCRIPTION_ID: ENC[AES256_GCM,data:axfnnc6Yo24TRsgmOig7VATBOO7s87Vo2yy/LOsJHn1KoI1R,iv:QOq/ocMxabsq0l89t8hZ6gSbDbvNMzDNiXwgKNdJ9l4=,tag:0rYMbIVCqzGjHYTg+c3Cxw==,type:str]
AZURE_CLIENT_ID: ENC[AES256_GCM,data:UzzZgyrrsGDgmH49MWTBC0/lzxlUxP8ABwH6wjvt0FIfuh4g,iv:MRnISPgmYoc8eFn7LXP6H4mDEWXuNOEcTb2kUg/1M5k=,tag:d9eJBetuEF3RTELSgyQOVQ==,type:str]
AZURE_CLIENT_SECRET: ENC[AES256_GCM,data:Ihx1go1jvZd61nb4bY+Vwyuf4g6U4fompgjR96XD+2W5g7TC2ySqvg==,iv:oasm3BPBVMuKfMY6Pw0WU3J1hXaGLF5MiYgxfIqfNiI=,tag:QLTJkkCWNCz+i5ayxEzhrg==,type:str]
AZURE_CLIENT_SECRET: ENC[AES256_GCM,data:IFvb59Gk/Hvr2LKef5jBwPeDWzjaI6E/Z5JNwWwZJ/X/zbk7F7h+/Q==,iv:0Gg6HOstjRory+JiNlKyPc1tsGl6BejSXAXp+JFMiHM=,tag:A1atnwbNn/hiOdFQ6AJXqQ==,type:str]
AZURE_TENANT_ID: ENC[AES256_GCM,data:dL69CpG0P/7uNSkbs4iWEfwEepyFDHYvKYWQb/+DMpKCNXRz,iv:BAPf7vO3W9j7GdNT9N3bN2MJmlHgzBIU77/oVGgf+DY=,tag:kIBbL4PDn4KgJTNYSNfugg==,type:str]
AZURE_PULUMI_LOCATION: ENC[AES256_GCM,data:HSJ4R+0typDoqPlvuiKxG0lag7u2C4eGTfmRg/349ZF1UAeOn0JGh6PMSCWct/agpuWv+qg=,iv:1NAH2+zZvVUtiuQrYg7soXFUBOU5ISJyL+zv6WIggoM=,tag:p2ZtLebf6Iu5Ivw2DEjPXQ==,type:str]
PULUMI_BACKEND_URL: ENC[AES256_GCM,data:ndLguPQ8Qvl4iT5B/YNA8AASikOc06URFCZuXjDJtsIlsvAhEwW2pIgmCkVggEBuC2dTfi0=,iv:bURpxt5L9x5eG+PX8IEre1UBxKlIL62DjmI9Bfy4ZHE=,tag:DyI80XTWueqLADw3SiFeCw==,type:str]
DIGITAL_OCEAN_DNS_PAT: ENC[AES256_GCM,data:POILwhJDKuQCiHyucptyDck/aIzXlrgtvwsiauaF3stTH865El/zgKRWKqS2xMY2tlCoPamEVF5fC0ffa9MXWMLcR9zK0Gg=,iv:Rz9MmwOjPtyrTs8W3TsljZv5M/fRukecX2fdHKPhcGU=,tag:zylfzsT4HUQqw8qBSxkPfw==,type:str]
sops:
azure_kv:
- created_at: "2026-07-02T22:29:03Z"
enc: M1PhjtgbWb9tsHWtbPPOM6Bpszej2gb_MGVNr-aRJ-wkurhltt1nHA9kPOl8eBhPRD3n9TRO9BLhClvH628FAvOWDmqnNWU4hC93p5f70BcIuDzKg3aDT1RLdjbE5fO1cZmOWpvPPXr8fhaNAqmjEyQaxV79fQFcpBOtj5YStiiLfeBTqyqoKxc3-ttClprctWFcn1dC5mr4itxh_ryMS-QkIX-xosDyzsalNpgOR4jiNc0-eVMF6b8bzTaiDdrS-7og3pdz8XAz3e2y2vl8ssYuaudZridTAuuQPPQMLIswlwtfxyaO2hLMqvyzT2ObEKUlAibxGC8CDshGhT5B1d7SXE4pNORIbfXDaETk89sh8pVUrTkadjh-rDRpzIh69K9Yvkd1zCDJrULZEV6DVwwLkKmVWBdi3lZnY5FOVNPFXsO0QAfPu3GXdUywt2J29FPP9KgeFbath2vXpqLIFH3BpLgJdWAa4np_ATLCKyuxAt7ioSm7OMoMG2kvX33tqC2tU8amlu4IF20aHDNBNFJB1HLSKbynzkeGdNtPxovmpYD628CifwkpgfWnS_hrWChng5i8RQi0cN9XcTKP3Uww7r4-rkCFp0s85e5KmAjsXUg1OXV56j_3dyI6ZeAso8ueycaVvxYnKN1Y1t9mJ0Sp8Nfx6ChYb94sovyBioQ
name: sops-administrators-key
vault_url: https://sops-administrators.vault.azure.net
version: 37bc81e975ea4a2194985560d066d52d
lastmodified: "2026-07-02T22:29:04Z"
mac: ENC[AES256_GCM,data:oI2BmQDHSdEOyJdN+buUm08hMjH2k4B6Kcfkm2rPjJIT6JNjTF1LVxQ6lK3VzYrWYqSl5YcMLcerkTEsD+WU694J2LBvNggfw3FKxjoz/michL5B0qyxovca6kAJ6ho+a1/3GOLR6V1dNcz8JyPFOZu+wDPYfnZyZIWQvf+njkQ=,iv:fJJQ+LsCVowQPYW8UjcwDuK0hPxpwKiRBCkD8jjPdgY=,tag:FW4XvGurDaXM9gBI1Rde4g==,type:str]
lastmodified: "2026-08-01T18:26:52Z"
mac: ENC[AES256_GCM,data:u1PB/9gCbPg8ZSL5e9C/dr9JfZ3NrCpbkJNzMirMUzgO6fntahsJatu0IWZ8B69AVfO8+DVNts0e8tbjhEAWWkQxmWJPTs2RZTE+TlvB2jszbMtaS8CLvuAF6exT1iSQmCF7E1t8huE8O5cyK9LFW705vdHTbdBWtrtDrtU9iIU=,iv:5MKl0uAusv7b1fuhEAhRs5jOH0TnjJr1ApQ5POlDNSw=,tag:/dqlgJ/iVqpcHbjleQ73tA==,type:str]
unencrypted_suffix: _unencrypted
version: 3.13.1
version: 3.13.3
5 changes: 3 additions & 2 deletions secrets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@ PG_ROLE_patchats-stg-app: ENC[AES256_GCM,data:x7K16UjqGLbYL8hE8eiE00BUAJLyCTqwwo
PG_ROLE_patchats-prod-app: ENC[AES256_GCM,data:T+Deyb6OVwHCuimUv6U2C6eG2u9zi9gYTdV95p+wykY=,iv:GdFQCqD8ceCCCdzO08mkTd80yASrVBsmPPKy+xVzV/A=,tag:gdJ6jsY5lRRlryTzfB1f+w==,type:str]
PG_ROLE_patchats-stg-ro: ENC[AES256_GCM,data:jEqekXU41TceQtTKErilTO1MmaExFun+9inpre9KpQA=,iv:DLrr1/pBLaHa/WwvAZrT/M4VxzYGGO7QbingkuyZqzk=,tag:SjmnWZccaXjARNQYvx9NWg==,type:str]
PG_ROLE_patchats-prod-ro: ENC[AES256_GCM,data:8J8a6LoIcBWjGAw5ZmgH1J4Nyybc9NuC5A4LMaGpKgY=,iv:JaifCIri3ZoQgmQok4mtAYGNNhEGWsQa8fCXrpRhyyU=,tag:1Awikh04S5ExCLur5hvIjw==,type:str]
PG_ROLE_grafana-all-ro-sa: ENC[AES256_GCM,data:7SWq7juAA+XKWY4KYWeE8Q11suy7pnEvjQCeiGY+HjQ=,iv:bhMtmaA8PMgREtVYEIRY++nIlHRc2y24nnLFDBSSEyQ=,tag:zaE7eL3m5fdrwOpZvb3+aw==,type:str]
sops:
azure_kv:
- created_at: "2026-04-23T06:04:34Z"
enc: J7COFDd-rnZOXfuBUJFVS6AvrZ8VA5Uu97Php4_0SiEIusrYafhGY5XNg1Ep8D1zep1TkZ163qrgZNy1RdoCd9r9s-4DULLygJ4nyUz-dVI7Bw5VmcNQKFpvatPQQau99GIxeBsmOMRZKV6XllYwi3xUD7zSIEH72KBaOeS3QDAIDjWlsF3BO2KK8-UWMDceZXW_i36agKp1ua8U8NvfKxhZe3yVx9P-kdLnS_RNjWnVIuHJy2wcHgQuCJCChr_lNLMB8Cj0d7fEhzjH01VsWAuaWlYD02l7HrIDBm9-sMkLWCV1z2GuQbO2xstukrHzzWpnyh8KvLRP__49ehdV0Q
name: sops-key
vault_url: https://sops-master.vault.azure.net
version: 90784f2986de4514934b4d1f682d3e59
lastmodified: "2026-07-02T22:20:58Z"
mac: ENC[AES256_GCM,data:8V/0EstscuMzjHxzcNlrooTrx8ScgKTQ1ieaYHAdkiaayDsKiGwhcW9SVPow2mXG2o2iOan5dhVGsqYVXLkLRaYqL0VezmADweR0xCfscfzDlhx/TKBOL6lOoi1OD23JBT+VaIFFSMYpG724ucg7U7KQwiYiMuyFCF/fy5sMdqI=,iv:bLZmO9rfNqim7MJ628Iop3nuIOZvkpS+IjFyACp3j6w=,tag:BgU3ddnjBTWfmzE/Jm31Lw==,type:str]
lastmodified: "2026-07-26T03:13:59Z"
mac: ENC[AES256_GCM,data:HlcOLXSYw85K0TDLBO60APZ4qp/1rdl5B34c5ANbSoeeOYXtBfpSilIUyIhLPwz77MXvvcNLBn6JzYuasOi0Vd2i82EP0Y265Wkq1k3MAHyo58VZWj1smHjUVKVGfK21GLMduye5AuLBNrhVbQHVvY9zuHmswu7v+p9F+9Q2Tyc=,iv:AHIzq8ez/R7MaLmYRJzheWZJop6alLrrKQYHtrVScog=,tag:m4+WPyHMkFIxfK+C+0W3SQ==,type:str]
unencrypted_suffix: _unencrypted
version: 3.13.1
107 changes: 77 additions & 30 deletions src/azure/users/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import * as azuread from "@pulumi/azuread";
import * as pulumi from "@pulumi/pulumi";
import * as random from "@pulumi/random";

import { azureadProvider as provider } from "@/azure/provider";
import { AZURE_USERS } from "@/azure/users/inputs";
import { split } from "@/utils";

const getUserImportId = (objectId: string) => `/users/${objectId}`;
const getUserResourceName = (firstName: string, lastName: string) =>
`azure-user-${firstName.toLowerCase()}-${lastName.toLowerCase()}`;

Expand All @@ -13,43 +14,89 @@ const fullName = <FS extends string, LS extends string>(
lastName: LS,
): `${FS} ${LS}` => `${firstName} ${lastName}`;

export const azureUsers = Object.fromEntries(
export const azureInitPws = Object.fromEntries(
Object.entries(AZURE_USERS)
.map(
([fullName, _]) =>
([fullName, u]) =>
[
{
firstName: split(fullName, " ")[0],
lastName: split(fullName, " ")[1],
},
_,
u,
] as const,
)
.map(([{ firstName, lastName }, user]) => [
fullName(firstName, lastName),
new azuread.User(
getUserResourceName(firstName, lastName),
{
displayName: fullName(firstName, lastName),
givenName: firstName,
mail: user.mail,
mailNickname: user.mailNickname,
surname: lastName,
userPrincipalName: user.userPrincipalName,
},
{
provider,
ignoreChanges: [
"forcePasswordChange",
"otherMails",
"usageLocation",
"preferredLanguage",
],
import:
user.bootstrapObjectId ?
getUserImportId(user.bootstrapObjectId)
: undefined,
},
),
.map(([{ firstName, lastName }, user]) => {
const pw = (() => {
if (user.newUser) {
return new random.RandomPassword(
`azure-user-init-pw-${firstName}-${lastName}`,
{
length: 20,
special: true,
},
);
}

return null;
})();

return [user.mail, pw];
}),
);

// so we can read output in pulumi state
export const azureInitPwsPlaintext = pulumi.secret(
Object.fromEntries(
Object.entries(AZURE_USERS).map(([_, user]) => [
user.mail,
azureInitPws[user.mail]?.result,
]),
),
);

export const azureUsers = Object.fromEntries(
Object.entries(AZURE_USERS)
.map(
([fullName, u]) =>
[
{
firstName: split(fullName, " ")[0],
lastName: split(fullName, " ")[1],
},
u,
] as const,
)
.map(([{ firstName, lastName }, user]) => {
const _fullName = fullName(firstName, lastName);

const pw = azureInitPws[user.mail];

return [
_fullName,
new azuread.User(
getUserResourceName(firstName, lastName),
{
displayName: _fullName,
givenName: firstName,
mail: user.mail,
mailNickname: user.mailNickname,
surname: lastName,
userPrincipalName: user.userPrincipalName,
password: pw?.result ?? undefined,
forcePasswordChange: user.newUser ? true : undefined,
},
{
provider,
ignoreChanges: [
"password",
"forcePasswordChange",
"otherMails",
"usageLocation",
"preferredLanguage",
],
},
),
];
}),
);
Loading
Loading