feat(SSO): メールアドレスのnormalizeを設定可能にする (MisskeyIO#971)

This commit is contained in:
あわわわとーにゅ 2025-04-22 00:14:13 +09:00 committed by GitHub
parent 17e14bb87e
commit c94e5d7e22
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 49 additions and 3 deletions

View file

@ -0,0 +1,11 @@
export class SSOWantEmailAddressNormalized1745247339195 {
name = 'SSOWantEmailAddressNormalized1745247339195'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "sso_service_provider" ADD "wantEmailAddressNormalized" boolean NOT NULL DEFAULT true`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "sso_service_provider" DROP COLUMN "wantEmailAddressNormalized"`);
}
}

View file

@ -79,4 +79,9 @@ export class MiSingleSignOnServiceProvider {
default: true,
})
public wantAssertionsSigned: boolean;
@Column('boolean', {
default: true,
})
public wantEmailAddressNormalized: boolean;
}

View file

@ -84,6 +84,10 @@ export const meta = {
type: 'boolean',
optional: false, nullable: false,
},
wantEmailAddressNormalized: {
type: 'boolean',
optional: false, nullable: false,
},
},
},
} as const;
@ -101,6 +105,7 @@ export const paramDef = {
cipherAlgorithm: { type: 'string', nullable: true },
wantAuthnRequestsSigned: { type: 'boolean', nullable: false, default: false },
wantAssertionsSigned: { type: 'boolean', nullable: false, default: true },
wantEmailAddressNormalized: { type: 'boolean', nullable: false, default: true },
useCertificate: { type: 'boolean', nullable: false, default: true },
secret: { type: 'string', nullable: true },
},
@ -157,6 +162,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
cipherAlgorithm: ps.cipherAlgorithm ? ps.cipherAlgorithm : null,
wantAuthnRequestsSigned: ps.wantAuthnRequestsSigned,
wantAssertionsSigned: ps.wantAssertionsSigned,
wantEmailAddressNormalized: ps.wantEmailAddressNormalized,
}).then(r => this.singleSignOnServiceProviderRepository.findOneByOrFail({ id: r.identifiers[0].id }));
this.moderationLogService.log(me, 'createSSOServiceProvider', {
@ -178,6 +184,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
cipherAlgorithm: ssoServiceProvider.cipherAlgorithm,
wantAuthnRequestsSigned: ssoServiceProvider.wantAuthnRequestsSigned,
wantAssertionsSigned: ssoServiceProvider.wantAssertionsSigned,
wantEmailAddressNormalized: ssoServiceProvider.wantEmailAddressNormalized,
};
});
}

View file

@ -77,6 +77,10 @@ export const meta = {
type: 'boolean',
optional: false, nullable: false,
},
wantEmailAddressNormalized: {
type: 'boolean',
optional: false, nullable: false,
},
},
},
},
@ -116,6 +120,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
cipherAlgorithm: service.cipherAlgorithm,
wantAuthnRequestsSigned: service.wantAuthnRequestsSigned,
wantAssertionsSigned: service.wantAssertionsSigned,
wantEmailAddressNormalized: service.wantEmailAddressNormalized,
}));
});
}

View file

@ -37,6 +37,7 @@ export const paramDef = {
cipherAlgorithm: { type: 'string', nullable: true },
wantAuthnRequestsSigned: { type: 'boolean', nullable: false },
wantAssertionsSigned: { type: 'boolean', nullable: false },
wantEmailAddressNormalized: { type: 'boolean', nullable: false },
regenerateCertificate: { type: 'boolean', nullable: true },
secret: { type: 'string', nullable: true },
},
@ -92,6 +93,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
cipherAlgorithm: ps.cipherAlgorithm !== '' ? ps.cipherAlgorithm : null,
wantAuthnRequestsSigned: ps.wantAuthnRequestsSigned,
wantAssertionsSigned: ps.wantAssertionsSigned,
wantEmailAddressNormalized: ps.wantEmailAddressNormalized,
});
const updatedService = await this.singleSignOnServiceProviderRepository.findOneByOrFail({ id: service.id });

View file

@ -180,7 +180,9 @@ export class JWTIdentifyProviderService {
preferred_username: user.username,
profile: `${this.config.url}/@${user.username}`,
picture: user.avatarUrl ?? undefined,
email: profile.emailVerified ? normalizeEmailAddress(profile.email) : `${user.username}@${this.config.hostname}`,
email: profile.emailVerified
? (ssoServiceProvider.wantEmailAddressNormalized ? normalizeEmailAddress(profile.email) : profile.email)
: `${user.username}@users.${this.config.hostname}`,
email_verified: profile.emailVerified,
mfa_enabled: profile.twoFactorEnabled,
updated_at: Math.floor((user.updatedAt?.getTime() ?? user.createdAt.getTime()) / 1000),

View file

@ -444,7 +444,9 @@ export class SAMLIdentifyProviderService {
'saml:Subject': {
'saml:NameID': {
'@Format': 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
'#text': profile.emailVerified ? normalizeEmailAddress(profile.email) : `${user.username}@${this.config.hostname}`,
'#text': profile.emailVerified
? (ssoServiceProvider.wantEmailAddressNormalized ? normalizeEmailAddress(profile.email) : profile.email)
: `${user.username}@users.${this.config.hostname}`,
},
'saml:SubjectConfirmation': {
'@Method': 'urn:oasis:names:tc:SAML:2.0:cm:bearer',
@ -569,7 +571,9 @@ export class SAMLIdentifyProviderService {
'@NameFormat': 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic',
'saml:AttributeValue': {
'@xsi:type': 'xs:string',
'#text': profile.emailVerified ? normalizeEmailAddress(profile.email) : `${user.username}@${this.config.hostname}`,
'#text': profile.emailVerified
? (ssoServiceProvider.wantEmailAddressNormalized ? normalizeEmailAddress(profile.email) : profile.email)
: `${user.username}@users.${this.config.hostname}`,
},
},
{