+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment
+
+$string['pluginname'] = 'OpenID Connect';
+$string['auth_oidcdescription'] = 'The OpenID Connect authentication plugin provides single-sign-on functionality using configurable IdP.';
+
+// Configuration pages.
+$string['settings_page_other_settings'] = 'Other options';
+$string['settings_page_application'] = 'IdP and authentication';
+$string['settings_page_binding_username_claim'] = 'Binding Username Claim';
+$string['settings_page_change_binding_username_claim_tool'] = 'Change binding username claim tool';
+$string['settings_page_cleanup_oidc_tokens'] = 'Cleanup OpenID Connect tokens';
+$string['settings_page_field_mapping'] = 'Field mappings';
+$string['heading_basic'] = 'Basic settings';
+$string['heading_basic_desc'] = '';
+$string['heading_additional_options'] = 'Additional options';
+$string['heading_additional_options_desc'] = '';
+$string['heading_user_restrictions'] = 'User restrictions';
+$string['heading_user_restrictions_desc'] = '';
+$string['heading_sign_out'] = 'Sign out integration';
+$string['heading_sign_out_desc'] = '';
+$string['heading_display'] = 'Display';
+$string['heading_display_desc'] = '';
+$string['heading_debugging'] = 'Debugging';
+$string['heading_debugging_desc'] = '';
+$string['idptype'] = 'Identity Provider (IdP) Type';
+$string['idptype_help'] = 'Three types of IdP are currently supported:
+
+- Microsoft Entra ID (v1.0): Microsoft Entra ID with oauth2 v1.0 endpoints, e.g. https://login.microsoftonline.com/organizations/oauth2/authorize.
+- Microsoft identity platform (v2.0): Microsoft Entra ID with oath2 v2.0 endpoints, e.g. https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize.
+- Other: any non Microsoft IdP.
+
+The differences between Microsoft Entra ID (v1.0) and Microsoft identity platform (v2.0) options can be found at https://docs.microsoft.com/en-us/azure/active-directory/azuread-dev/azure-ad-endpoint-comparison.
+Notably, the configured application can use certificate besides secret for authentication when using Microsoft identity platform (v2.0) IdP.
+Authorization and token endpoints need to be configured according to the configured IdP type.';
+$string['idp_type_microsoft_entra_id'] = 'Microsoft Entra ID (v1.0)';
+$string['idp_type_microsoft_identity_platform'] = 'Microsoft identity platform (v2.0)';
+$string['idp_type_other'] = 'Other';
+$string['cfg_authenticationlink_desc'] = 'Link to IdP and authentication configuration';
+$string['authendpoint'] = 'Authorization Endpoint';
+$string['authendpoint_help'] = 'The URI of the Authorization endpoint from your IdP to use.
+Note if the site is to be configured to allow users from other tenants to access, tenant specific authorization endpoint cannot be used.';
+$string['cfg_autoappend_key'] = 'Auto-Append';
+$string['cfg_autoappend_desc'] = 'Automatically append this string when logging in users using the "Resource Owner Password Credentials" authentication method. This is useful when your IdP requires a common domain, but don\'t want to require users to type it in when logging in. For example, if the full OpenID Connect user is "james@example.com" and you enter "@example.com" here, the user will only have to enter "james" as their username.
Note: In the case where conflicting usernames exist - i.e. a Moodle user exists wth the same name, the priority of the authentication plugin is used to determine which user wins out.';
+$string['clientid'] = 'Application ID';
+$string['clientid_help'] = 'The registered Application / Client ID on the IdP.';
+$string['clientauthmethod'] = 'Client authentication method';
+$string['clientauthmethod_help'] = '
+- IdP in all types can use "Secret" authentication method.
+- IdP in Microsoft identity platform (v2.0) type can additionally use Certificate authentication method.
+
';
+$string['auth_method_secret'] = 'Secret';
+$string['auth_method_certificate'] = 'Certificate';
+$string['clientsecret'] = 'Client Secret';
+$string['clientsecret_help'] = 'When using secret authentication method, this is the client secret on the IdP. On some providers, it is also referred to as a key.';
+$string['clientprivatekey'] = 'Client certificate private key';
+$string['clientprivatekey_help'] = 'When using certificate authentication method and Plain text certificate source, this is the private key of the certificate used to authenticate with IdP.';
+$string['clientcert'] = 'Client certificate public key';
+$string['clientcert_help'] = 'When using certificate authentication method and Plain text certificate source, this is the public key, or certificate, used in to authenticate with IdP.';
+$string['clientcertsource'] = 'Certificate source';
+$string['clientcertsource_help'] = 'When using certificate authentication method, this is used to define where to retrieve the certificate from.
+
+- Plain text source requires the certificate/private key file contents to be configured in the subsequent text area settings.
+- File name source requires the certificate/private key files exist in a folder microsoft_certs in the Moodle data folder.
+
';
+$string['cert_source_text'] = 'Plain text';
+$string['cert_source_path'] = 'File name';
+$string['clientprivatekeyfile'] = 'File name of client certificate private key';
+$string['clientprivatekeyfile_help'] = 'When using certificate authentication method and File name certificate source, this is the file name of private key used to authenticate with IdP. The file needs to present in a folder microsoft_certs in the Moodle data folder.';
+$string['clientcertfile'] = 'File name of client certificate public key';
+$string['clientcertfile_help'] = 'When using certificate authentication method and File name certificate source, this is the file name of public key, or certificate, used to authenticate with IdP. The file needs to present in a folder microsoft_certs in the Moodle data folder.';
+$string['clientcertpassphrase'] = 'Client certificate passphrase';
+$string['clientcertpassphrase_help'] = 'If the client certificate private key is encrypted, this is the passphrase to decrypt it.';
+$string['cfg_domainhint_key'] = 'Domain Hint';
+$string['cfg_domainhint_desc'] = 'When using the Authorization Code login flow, pass this value as the "domain_hint" parameter. "domain_hint" is used by some OpenID Connect IdP to make the login process easier for users. Check with your provider to see whether they support this parameter.';
+$string['cfg_err_invalidauthendpoint'] = 'Invalid Authorization Endpoint';
+$string['cfg_err_invalidtokenendpoint'] = 'Invalid Token Endpoint';
+$string['cfg_err_invalidclientid'] = 'Invalid client ID';
+$string['cfg_err_invalidclientsecret'] = 'Invalid client secret';
+$string['cfg_forceredirect_key'] = 'Force redirect';
+$string['cfg_forceredirect_desc'] = 'If enabled, will skip the login index page and redirect to the OpenID Connect page. Can be bypassed with ?noredirect=1 URL param';
+$string['cfg_icon_key'] = 'Icon';
+$string['cfg_icon_desc'] = 'An icon to display next to the provider name on the login page.';
+$string['cfg_iconalt_o365'] = 'Microsoft 365 icon';
+$string['cfg_iconalt_locked'] = 'Locked icon';
+$string['cfg_iconalt_lock'] = 'Lock icon';
+$string['cfg_iconalt_go'] = 'Green circle';
+$string['cfg_iconalt_stop'] = 'Red circle';
+$string['cfg_iconalt_user'] = 'User icon';
+$string['cfg_iconalt_user2'] = 'User icon alternate';
+$string['cfg_iconalt_key'] = 'Key icon';
+$string['cfg_iconalt_group'] = 'Group icon';
+$string['cfg_iconalt_group2'] = 'Group icon alternate';
+$string['cfg_iconalt_mnet'] = 'MNET icon';
+$string['cfg_iconalt_userlock'] = 'User with lock icon';
+$string['cfg_iconalt_plus'] = 'Plus icon';
+$string['cfg_iconalt_check'] = 'Checkmark icon';
+$string['cfg_iconalt_rightarrow'] = 'Right-facing arrow icon';
+$string['cfg_customicon_key'] = 'Custom Icon';
+$string['cfg_customicon_desc'] = 'If you\'d like to use your own icon, upload it here. This overrides any icon chosen above.
Notes on using custom icons:- This image will not be resized on the login page, so we recommend uploading an image no bigger than 35x35 pixels.
- If you have uploaded a custom icon and want to go back to one of the stock icons, click the custom icon in the box above, then click "Delete", then click "OK", then click "Save Changes" at the bottom of this form. The selected stock icon will now appear on the Moodle login page.
';
+$string['cfg_debugmode_key'] = 'Record debug messages';
+$string['cfg_debugmode_desc'] = 'If enabled, information will be logged to the Moodle log that can help in identifying problems.';
+$string['cfg_loginflow_key'] = 'Login Flow';
+$string['cfg_loginflow_authcode'] = 'Authorization Code Flow (recommended)';
+$string['cfg_loginflow_authcode_desc'] = 'Using this flow, the user clicks the name of the IdP (See "Provider Display Name" above) on the Moodle login page and is redirected to the provider to log in. Once successfully logged in, the user is redirected back to Moodle where the Moodle login takes place transparently. This is the most standardized, secure way for the user log in.';
+$string['cfg_loginflow_rocreds'] = 'Resource Owner Password Credentials Grant (deprecated)';
+$string['cfg_loginflow_rocreds_desc'] = 'This login flow is deprecated and will be removed from the plugin soon.
Using this flow, the user enters their username and password into the Moodle login form like they would with a manual login. This will authorize the user with the IdP, but will not create a session on the IdP\'s site. For example, if using Microsoft 365 with OpenID Connect, the user will be logged in to Moodle but not the Microsoft 365 web applications. Using the authorization request is recommended if you want users to be logged in to both Moodle and the IdP. Note that not all IdP support this flow. This option should only be used when other authorization grant types are not available.';
+$string['cfg_silentloginmode_key'] = 'Silent Login Mode';
+$string['cfg_silentloginmode_desc'] = 'If enabled, Moodle will try to use the active session of a user authenticated to the configured authorization endpoint to log the user in.
+To use this feature, the following configurations are required:
+
+- Force users to log in (forcelogin) in the Site policies section is enabled.
+- Force redirect (auth_oidc/forceredirect) setting above is enabled.
+
+In order to avoid Moodle trying to use personal accounts or accounts from other tenants to login, it is also recommended to use tenant specific endpoints, rather than generic ones using "common" or "organization" etc. paths.
+
+For Microsoft IdPs, the user experience is as follows:
+
+- If no active user session is found, Moodle login page will show.
+- If only one active user session is found, and the user has access to the Entra ID app (i.e. user is from the same tenant, or is a guest user of the tenant), the user will be logged in to Moodle automatically using SSO.
+- If only one active user session is found, but the user doesn\'t have access to the Entra ID app (e.g. the user is from a different tenant, or the app requires user assignment and the user isn\'t assigned), the Moodle login page will show.
+- If there are multiple active user sessions who have access to the Entra ID app, a page will show to allow the user to select the account to log in with.
+
';
+$string['oidcresource'] = 'Resource';
+$string['oidcresource_help'] = 'The OpenID Connect resource for which to send the request.
+Note this is paramater is not supported in Microsoft identity platform (v2.0) IdP type.';
+$string['oidcscope'] = 'Scope';
+$string['oidcscope_help'] = 'The OIDC Scope to use.';
+$string['secretexpiryrecipients'] = 'Secret Expiry Notification Recipients';
+$string['secretexpiryrecipients_help'] = 'A comma-separated list of email addresses to send secret expiry notifications to.
+If no email address is entered, the main site administrator will be notified.';
+$string['cfg_opname_key'] = 'Provider Display Name';
+$string['cfg_opname_desc'] = 'This is an end-user-facing label that identifies the type of credentials the user must use to login. This label is used throughout the user-facing portions of this plugin to identify your provider.';
+$string['cfg_redirecturi_key'] = 'Redirect URI';
+$string['cfg_redirecturi_desc'] = 'This is the URI to register as the "Redirect URI". Your OpenID Connect IdP should ask for this when registering Moodle as a client.
NOTE: You must enter this in your OpenID Connect IdP *exactly* as it appears here. Any difference will prevent logins using OpenID Connect.';
+$string['tokenendpoint'] = 'Token Endpoint';
+$string['tokenendpoint_help'] = 'The URI of the token endpoint from your IdP to use.
+Note if the site is to be configured to allow users from other tenants to access, tenant specific token endpoint cannot be used.';
+$string['cfg_userrestrictions_key'] = 'User Restrictions';
+$string['cfg_userrestrictions_desc'] = 'Only allow users to log in that meet certain restrictions.
How to use user restrictions: - Enter a regular expression pattern that matches the usernames of users you want to allow.
- Enter one pattern per line
- If you enter multiple patterns a user will be allowed if they match ANY of the patterns.
- The character "/" should be escaped with "\".
- If you don\'t enter any restrictions above, all users that can log in to the OpenID Connect IdP will be accepted by Moodle.
- Any user that does not match any entered pattern(s) will be prevented from logging in using OpenID Connect.
';
+$string['cfg_userrestrictionscasesensitive_key'] = 'User Restrictions Case Sensitive';
+$string['cfg_userrestrictionscasesensitive_desc'] = 'This controls if the "/i" option in regular expression is used in the user restriction match.
If enabled, all user restriction checks will be performed as with case sensitive. Note if this is disabled, any patterns on letter cases will be ignored.';
+$string['cfg_signoffintegration_key'] = 'Single Sign Out (from Moodle to IdP)';
+$string['cfg_signoffintegration_desc'] = 'If the option is enabled, when a Moodle user connected to the configured IdP logs out of Moodle, the integration will trigger a request at the logout endpiont below, attempting to log the user off from IdP as well.
+Note for integration with Microsoft Entra ID, the URL of Moodle site ({$a}) needs to be added as a redirect URI in the Azure app created for Moodle and Microsoft 365 integration.';
+$string['cfg_logoutendpoint_key'] = 'IdP Logout Endpoint';
+$string['cfg_logoutendpoint_desc'] = 'The URI of the logout endpoint from your IdP to use.';
+$string['cfg_frontchannellogouturl_key'] = 'Front-channel Logout URL';
+$string['cfg_frontchannellogouturl_desc'] = 'This is the URL that your IdP needs to trigger when it tries to log users out of Moodle.
+For Microsoft Entra ID / Microsoft identity platform, the setting is called "Front-channel logout URL" and is configurable in the Azure app.';
+$string['cfg_field_mapping_desc'] = 'User profile data can be mapped from Open ID Connect IdP to Moodle. The remote fields available to map heavily depends on the IdP type.
+
+- Some basic profile fields are available from access token and ID token claims from all IdP types.
+- If Microsoft IdP type is configured (either v1.0 or v2.0), additional profile data can be made available via Graph API calls by installing and configuring the Microsoft 365 integration plugin (local_o365).
+- If SDS profile sync feature is enabled in the local_o365 plugin, certain profile fields can be synchronised from SDS to Moodle. when running the "Sync with SDS" scheduled task, and will not happen when running the "Sync users with Microsoft Entra ID" scheduled task, nor when user logs in.
+
+
+The claims available from the ID and access tokens vary depending on IdP type, but most IdP allows some level of customisation of the claims. Documentation on Microsoft IdPs are linked below:
+';
+
+$string['cfg_cleanupoidctokens_key'] = 'Cleanup OpenID Connect Tokens';
+$string['cfg_cleanupoidctokens_desc'] = 'If your users are experiencing problems logging in using their Microsoft 365 account, trying cleaning up OpenID Connect tokens. This removes stray and incomplete tokens that can cause errors. WARNING: This may interrupt logins in-process, so it\'s best to do this during downtime.';
+$string['settings_section_basic'] = 'Basic settings';
+$string['settings_section_authentication'] = 'Authentication';
+$string['settings_section_endpoints'] = 'Endpoints';
+$string['settings_section_binding_username_claim'] = 'Binding Username Claim';
+$string['settings_section_other_params'] = 'Other parameters';
+$string['settings_section_secret_expiry_notification'] = 'Secret expiry notification';
+$string['authentication_and_endpoints_saved'] = 'Authentication and endpoint settings updated.';
+$string['application_updated'] = 'OpenID Connect application setting have been updated.';
+$string['application_updated_microsoft'] = 'OpenID Connect application setting was updated.
+Azure administrator will need to Provide admin consent and Verify setup again on the Microsoft 365 integration configuration page if "Identity Provider (IdP) Type" or "Client authentication method" settings are updated.';
+$string['application_not_changed'] = 'OpenID Connect application setting was not changed.';
+
+$string['event_debug'] = 'Debug message';
+
+$string['task_cleanup_oidc_state_and_token'] = 'Clean up OIDC state and invalid token';
+$string['task_cleanup_oidc_sid'] = 'Clean up OIDC SID records';
+
+$string['errorauthdisconnectemptypassword'] = 'Password cannot be empty';
+$string['errorauthdisconnectemptyusername'] = 'Username cannot be empty';
+$string['errorauthdisconnectusernameexists'] = 'That username is already taken. Please choose a different one.';
+$string['errorauthdisconnectnewmethod'] = 'Use Login Method';
+$string['errorauthdisconnectinvalidmethod'] = 'Invalid login method received.';
+$string['errorauthdisconnectifmanual'] = 'If using the manual login method, enter credentials below.';
+$string['errorauthdisconnectinvalidmethod'] = 'Invalid login method received.';
+$string['errorauthgeneral'] = 'There was a problem logging you in. Please contact your administrator for assistance.';
+$string['errorauthinvalididtoken'] = 'Invalid id_token received.';
+$string['errorauthloginfailednouser'] = 'Invalid login: User not found in Moodle. If this site has the "authpreventaccountcreation" setting enabled, this may mean you need an administrator to create an account for you first.';
+$string['errorauthloginfaileddupemail'] = 'Invalid login: An existing account on this Moodle has the same email address as the account you try to create, and "Allow accounts with same email" (allowaccountssameemail) setting is disabled.';
+$string['errorauthnoauthcode'] = 'No authorization code was received from the identity server. The error logs may have more information.';
+$string['errorauthnocredsandendpoints'] = 'Please configure OpenID Connect client credentials and endpoints.';
+$string['errorauthnohttpclient'] = 'Please set an HTTP client.';
+$string['errorauthnoidtoken'] = 'OpenID Connect id_token not received.';
+$string['errorauthnoaccesstoken'] = 'Access token not received.';
+$string['errorauthunknownstate'] = 'Unknown state.';
+$string['errorauthuseralreadyconnected'] = 'You\'re already connected to a different OpenID Connect user.';
+$string['errorauthuserconnectedtodifferent'] = 'The OpenID Connect user that authenticated is already connected to a Moodle user.';
+$string['errorbadloginflow'] = 'Invalid authentication type specified. Note: If you are receiving this after a recent installation or upgrade, please clear your Moodle cache.';
+$string['errorjwtbadpayload'] = 'Could not read JWT payload.';
+$string['errorjwtcouldnotreadheader'] = 'Could not read JWT header';
+$string['errorjwtempty'] = 'Empty or non-string JWT received.';
+$string['errorjwtinvalidheader'] = 'Invalid JWT header';
+$string['errorjwtmalformed'] = 'Malformed JWT received.';
+$string['errorjwtunsupportedalg'] = 'JWS Alg or JWE not supported';
+$string['errorlogintoconnectedaccount'] = 'This Microsoft 365 user is connected to a Moodle account, but OpenID Connect login is not enabled for this Moodle account. Please log in to the Moodle account using the account\'s defined authentication method to use Microsoft 365 features';
+$string['erroroidcnotenabled'] = 'The OpenID Connect authentication plugin is not enabled.';
+$string['errornodisconnectionauthmethod'] = 'Cannot disconnect because there is no enabled authentication plugin to fall back to. (either user\'s previous login method or the manual login method).';
+$string['erroroidcclientinvalidendpoint'] = 'Invalid Endpoint URI received.';
+$string['erroroidcclientnocreds'] = 'Please set client credentials with setcreds';
+$string['erroroidcclientnoauthendpoint'] = 'No authorization endpoint set. Please set with $this->setendpoints';
+$string['erroroidcclientnotokenendpoint'] = 'No token endpoint set. Please set with $this->setendpoints';
+$string['erroroidcclientinsecuretokenendpoint'] = 'The token endpoint must be using SSL/TLS for this.';
+$string['errorrestricted'] = 'This site has restrictions in place on the users that can log in with OpenID Connect. These restrictions currently prevent you from completing this login attempt.';
+$string['errorucpinvalidaction'] = 'Invalid action received.';
+$string['erroroidccall'] = 'Error in OpenID Connect. Please check logs for more information.';
+$string['erroroidccall_message'] = 'Error in OpenID Connect: {$a}';
+$string['errorinvalidredirect_message'] = 'The URL you are trying to redirect to does not exist.';
+$string['errorinvalidcertificatesource'] = 'Invalid certificate source';
+$string['error_empty_tenantnameorguid'] = 'Tenant name or GUID cannot be empty when using Microsoft Entra ID (v1.0) or Microsoft identity platform (v2.0) IdPs.';
+$string['error_invalid_client_authentication_method'] = "Invalid client authentication method";
+$string['error_empty_client_secret'] = 'Client secret cannot be empty when using "secret" authentication method';
+$string['error_empty_client_private_key'] = 'Client certificate private key cannot be empty when using "certificate" authentication method';
+$string['error_empty_client_cert'] = 'Client certificate public key cannot be empty when using "certificate" authentication method';
+$string['error_empty_client_private_key_file'] = 'Client certificate private key file cannot be empty when using "certificate" authentication method';
+$string['error_empty_client_cert_file'] = 'Client certificate public key file cannot be empty when using "certificate" authentication method';
+$string['error_empty_tenantname_or_guid'] = 'Tenant name or GUID cannot be empty when using "certificate" authentication method';
+$string['error_endpoint_mismatch_auth_endpoint'] = 'The configured authorization endpoint does not match configured IdP type.
+
+- When using "Microsoft Entra ID (v1.0)" IdP type, use v1.0 endpoint, e.g. https://login.microsoftonline.com/organizations/oauth2/authorize
+- When using "Microsoft identity platform (v2.0)" IdP type, use v2.0 endpoint, e.g. https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize
+
';
+$string['error_endpoint_mismatch_token_endpoint'] = 'The configured token endpoint does not match configured IdP type.
+
+- When using "Microsoft Entra ID (v1.0)" IdP type, use v1.0 endpoint, e.g. https://login.microsoftonline.com/organizations/oauth2/token
+- When using "Microsoft identity platform (v2.0)" IdP type, use v2.0 endpoint, e.g. https://login.microsoftonline.com/organizations/oauth2/v2.0/token
+
';
+$string['error_tenant_specific_endpoint_required'] = 'When using "Microsoft identity platform (v2.0)" IdP type and "Certificate" authentication method, tenant specific endpoint (i.e. not common/organizations/consumers) is required.';
+$string['error_empty_oidcresource'] = 'Resource cannot be empty when using Microsoft Entra ID (v1.0) or other types of IdP.';
+$string['erroruserwithusernamealreadyexists'] = 'Error occurred when trying to rename your Moodle account. A Moodle user with the new username already exists. Ask your site administrator to resolve this first.';
+$string['error_no_response_available'] = 'No responses available.';
+
+$string['eventuserauthed'] = 'User Authorized with OpenID Connect';
+$string['eventusercreated'] = 'User created with OpenID Connect';
+$string['eventuserconnected'] = 'User connected to OpenID Connect';
+$string['eventuserloggedin'] = 'User Logged In with OpenID Connect';
+$string['eventuserdisconnected'] = 'User disconnected from OpenID Connect';
+$string['eventuserrenameattempt'] = 'The auth_oidc plugin attempted to rename a user';
+
+$string['oidc:manageconnection'] = 'Allow OpenID Connection and Disconnection';
+$string['oidc:manageconnectionconnect'] = 'Allow OpenID Connection';
+$string['oidc:manageconnectiondisconnect'] = 'Allow OpenID Disconnection';
+
+$string['privacy:metadata:auth_oidc'] = 'OpenID Connect Authentication';
+$string['privacy:metadata:auth_oidc_prevlogin'] = 'Previous login methods to undo Microsoft 365 connections';
+$string['privacy:metadata:auth_oidc_prevlogin:userid'] = 'The ID of the Moodle user';
+$string['privacy:metadata:auth_oidc_prevlogin:method'] = 'The previous login method';
+$string['privacy:metadata:auth_oidc_prevlogin:password'] = 'The previous (encrypted) user password field.';
+$string['privacy:metadata:auth_oidc_token'] = 'OpenID Connect tokens';
+$string['privacy:metadata:auth_oidc_token:oidcuniqid'] = 'The OIDC unique user identifier.';
+$string['privacy:metadata:auth_oidc_token:username'] = 'The username of the Moodle user';
+$string['privacy:metadata:auth_oidc_token:userid'] = 'The user ID of the Moodle user';
+$string['privacy:metadata:auth_oidc_token:oidcusername'] = 'The username of the OIDC user';
+$string['privacy:metadata:auth_oidc_token:useridentifier'] = 'The user identifier of the OIDC user';
+$string['privacy:metadata:auth_oidc_token:scope'] = 'The scope of the token';
+$string['privacy:metadata:auth_oidc_token:tokenresource'] = 'The resource of the token';
+$string['privacy:metadata:auth_oidc_token:authcode'] = 'The auth code for the token';
+$string['privacy:metadata:auth_oidc_token:token'] = 'The token';
+$string['privacy:metadata:auth_oidc_token:expiry'] = 'The token expiry';
+$string['privacy:metadata:auth_oidc_token:refreshtoken'] = 'The refresh token';
+$string['privacy:metadata:auth_oidc_token:idtoken'] = 'The ID token';
+
+// In the following strings, $a refers to a customizable name for the identity manager. For example, this could be
+// "Microsoft 365", "OpenID Connect", etc.
+$string['ucp_general_intro'] = 'Here you can manage your connection to {$a}. If enabled, you will be able to use your {$a} account to log in to Moodle instead of a separate username and password. Once connected, you\'ll no longer have to remember a username and password for Moodle, all log-ins will be handled by {$a}.';
+$string['ucp_login_start'] = 'Start using {$a} to log in to Moodle';
+$string['ucp_login_start_desc'] = 'This will switch your account to use {$a} to log in to Moodle. Once enabled, you will log in using your {$a} credentials - your current Moodle username and password will not work. You can disconnect your account at any time and return to logging in normally.';
+$string['ucp_login_stop'] = 'Stop using {$a} to log in to Moodle';
+$string['ucp_login_stop_desc'] = 'You are currently using {$a} to log in to Moodle. Clicking "Stop using {$a} login" will disconnect your Moodle account from {$a}. You will no longer be able to log in to Moodle with your {$a} account. You\'ll be asked to create a username and password, and from then on you will then be able to log in to Moodle directly.';
+$string['ucp_login_status'] = '{$a} login is:';
+$string['ucp_status_enabled'] = 'Enabled';
+$string['ucp_status_disabled'] = 'Disabled';
+$string['ucp_disconnect_title'] = '{$a} Disconnection';
+$string['ucp_disconnect_details'] = 'This will disconnect your Moodle account from {$a}. You\'ll need to create a username and password to log in to Moodle.';
+$string['ucp_title'] = '{$a} Management';
+$string['ucp_o365accountconnected'] = 'This Microsoft 365 account is already connected with another Moodle account.';
+
+// Clean up OIDC tokens.
+$string['cleanup_oidc_tokens'] = 'Cleanup OpenID Connect tokens';
+$string['unmatched'] = 'Unmatched';
+$string['delete_token'] = 'Delete token';
+$string['mismatched'] = 'Mismatched';
+$string['na'] = 'n/a';
+$string['mismatched_details'] = 'Token record contains username "{$a->tokenusername}"; matched Moodle user has username "{$a->moodleusername}".';
+$string['delete_token_and_reference'] = 'Delete token and reference';
+$string['table_token_id'] = 'Token record ID';
+$string['table_oidc_username'] = 'OIDC username';
+$string['table_oidc_unique_identifier'] = 'OIDC unique identifier';
+$string['table_token_unique_id'] = 'OIDC unique ID';
+$string['table_matching_status'] = 'Matching status';
+$string['table_matching_details'] = 'Details';
+$string['table_action'] = 'Action';
+$string['token_deleted'] = 'Token was deleted successfully';
+$string['no_token_to_cleanup'] = 'There are no OIDC token to cleanup.';
+
+$string['errorusermatched'] = 'The Microsoft 365 account "{$a->entraidupn}" is already matched with Moodle user "{$a->username}". To complete the connection, please log in as that Moodle user first and follow the instructions in the Microsoft block.';
+
+// User mapping options.
+$string['update_oncreate_and_onlogin'] = 'On creation and every login';
+$string['update_oncreate_and_onlogin_and_usersync'] = 'On creation, every login, and every user sync task run';
+$string['update_onlogin_and_usersync'] = 'On every login and every user sync task run';
+
+// Remote fields.
+$string['settings_fieldmap_feild_not_mapped'] = '(not mapped)';
+$string['settings_fieldmap_field_bindingusernameclaim'] = 'Binding Username Claim (can only be mapped during login)';
+$string['settings_fieldmap_field_city'] = 'City';
+$string['settings_fieldmap_field_companyName'] = 'Company Name';
+$string['settings_fieldmap_field_objectId'] = 'Object ID';
+$string['settings_fieldmap_field_country'] = 'Country';
+$string['settings_fieldmap_field_department'] = 'Department';
+$string['settings_fieldmap_field_displayName'] = 'Display Name';
+$string['settings_fieldmap_field_surname'] = 'Surname';
+$string['settings_fieldmap_field_faxNumber'] = 'Fax Number';
+$string['settings_fieldmap_field_telephoneNumber'] = 'Telephone Number';
+$string['settings_fieldmap_field_givenName'] = 'Given Name';
+$string['settings_fieldmap_field_jobTitle'] = 'Job Title';
+$string['settings_fieldmap_field_mail'] = 'Email';
+$string['settings_fieldmap_field_mobile'] = 'Mobile';
+$string['settings_fieldmap_field_postalCode'] = 'Postal Code';
+$string['settings_fieldmap_field_preferredLanguage'] = 'Language';
+$string['settings_fieldmap_field_state'] = 'State';
+$string['settings_fieldmap_field_streetAddress'] = 'Street Address';
+$string['settings_fieldmap_field_userPrincipalName'] = 'User Principal Name';
+$string['settings_fieldmap_field_employeeId'] = 'Employee ID';
+$string['settings_fieldmap_field_businessPhones'] = 'Office phone';
+$string['settings_fieldmap_field_mobilePhone'] = 'Mobile phone';
+$string['settings_fieldmap_field_officeLocation'] = 'Office';
+$string['settings_fieldmap_field_preferredName'] = 'Preferred Name';
+$string['settings_fieldmap_field_manager'] = 'Manager name';
+$string['settings_fieldmap_field_manager_email'] = 'Manager email';
+$string['settings_fieldmap_field_teams'] = 'Teams';
+$string['settings_fieldmap_field_groups'] = 'Groups';
+$string['settings_fieldmap_field_roles'] = 'Roles';
+$string['settings_fieldmap_field_onPremisesSamAccountName'] = 'On-premises SAM account name';
+$string['settings_fieldmap_field_extensionattribute'] = 'Extension attribute {$a}';
+$string['settings_fieldmap_field_sds_school_id'] = 'SDS school ID ({$a})';
+$string['settings_fieldmap_field_sds_school_name'] = 'SDS school name ({$a})';
+$string['settings_fieldmap_field_sds_school_role'] = 'SDS school role ("Student" or "Teacher")';
+$string['settings_fieldmap_field_sds_student_externalId'] = 'SDS student external ID';
+$string['settings_fieldmap_field_sds_student_birthDate'] = 'SDS student birth date';
+$string['settings_fieldmap_field_sds_student_grade'] = 'SDS student grade';
+$string['settings_fieldmap_field_sds_student_graduationYear'] = 'SDS student graduation year';
+$string['settings_fieldmap_field_sds_student_studentNumber'] = 'SDS student number';
+$string['settings_fieldmap_field_sds_teacher_externalId'] = 'SDS teacher external ID';
+$string['settings_fieldmap_field_sds_teacher_teacherNumber'] = 'SDS teacher number';
+
+// Binding username claim options.
+$string['binding_username_claim_heading'] = 'Binding Username Claim';
+$string['binding_username_claim_description'] = '
+This page allows site administrators to select the token claim to use for binding with Moodle username.
+Be very cautious when changing this setting. Follow the steps below to change this setting on Moodle sites with existing users using OpenID Connect authentication method. Failure to do so may result in users being logged out and/or duplicate accounts being created.
+
+- Make sure you have a manual site administrator account, i.e. not using OpenID Connect authentication method.
+- Schedule enough downtime and put the Moodle site into maintenance mode.
+- Backup Moodle database, in particular user and auth_oidc_tokens tables. If local_o365 plugin is installed, backup local_o365_objects table too.
+- Use the update binding username tool to update Moodle username, auth_oidc token, and other connection records of the existing user to match the value of the claim to be changed to.
+- Update the binding username token setting on this page.
+- Purge caches.
+- Move the Moodle site out of maintenance mode.
+
+In most cases this setting should be set to the default option "Choose automatically", meaning the plugin will try to determine the token to use depending on IdP type. Misconfiguration or unexpected change of this setting will result in SSO failure.
';
+$string['binding_username_claim_description_existing_claims'] = 'The following claims are present in existing user ID tokens. Choose claims not on the list may results in SSO failure.
+{$a}
';
+$string['binding_username_auto'] = 'Choose automatically';
+$string['binding_username_custom'] = 'Custom';
+$string['bindingusernameclaim'] = 'Binding username claim';
+$string['customclaimname'] = 'Custom claim name';
+$string['customclaimname_description'] = 'This field is used only when the Binding Username Claim setting is set to Custom.';
+$string['binding_username_claim_help_ms_no_user_sync'] = 'The options for non Microsoft IdPs include:
+
+- Choose automatically: Uses current logic, determining the token by IdP type and falling back to sub if no claim is found.
+- preferred_username: Default for Microsoft identity platform (v2.0) IdP type. Does not support user sync.
+- email: Fallback for Microsoft identity platform (v2.0).
+- upn: Default for Microsoft Entra ID (v1.0) and other IdP types.
+- unique_name: Fallback for Microsoft Entra ID (v1.0) and other IdP types. Does not support user sync.
+- oid: Fallback if no other claims are present. Only present in Microsoft IdP.
+- sub: Fallback if no other claims are present. Does not support user sync.
+- samaccountname: Custom claim.
+- Custom: Allows the site admin to enter a custom value. Does not support user sync.
+
+Note some options do not support user sync.';
+$string['binding_username_claim_help_ms_with_user_sync'] = 'The options for Microsoft IdP with user sync feature enabled include:
+
+- Choose automatically: Uses current logic, determining the token by IdP type and falling back to sub if no claim is found.
+- email: Fallback for Microsoft identity platform (v2.0).
+- upn: Default for Microsoft Entra ID (v1.0) and other IdP types.
+- oid: Fallback if no other claims are present. Only present in Microsoft IdP.
+- samaccountname: Custom claim.
+
';
+$string['binding_username_claim_help_non_ms'] = 'The options for Microsoft IdP without user sync feature enabled include:
+
+- Choose automatically: Uses current logic, determining the token by IdP type and falling back to sub if no claim is found.
+- preferred_username
+- email
+- unique_name
+- sub
+- samaccountname
+- custom: Custom claim.
+
';
+$string['binding_username_claim_updated'] = 'Binding Username Claim was updated successfully.';
+$string['examplecsv'] = 'Example upload file';
+$string['usernamefile'] = 'File';
+$string['csvdelimiter'] = 'CSV separator';
+$string['encoding'] = 'Encoding';
+$string['rowpreviewnum'] = 'Preview rows';
+$string['upload_usernames'] = 'Update binding usernames';
+$string['update_stats_users_updated'] = '{$a} users were updated';
+$string['update_stats_users_errors'] = '{$a} users had errors';
+$string['update_error_incomplete_line'] = 'The line does not contain required fields.';
+$string['update_error_user_not_found'] = 'No user found matching the username. Will try update manually matched user.';
+$string['update_error_user_not_oidc'] = 'The user is not using OpenID Connect authentication method. Will try update manually matched user.';
+$string['update_error_invalid_new_username'] = 'New username is invalid.';
+$string['update_error_user_update_failed'] = 'Failed to update user.';
+$string['update_warning_email_match'] = 'Email matches existing user.';
+$string['update_success_username'] = 'Username updated successfully.';
+$string['update_success_token'] = 'Token updated successfully.';
+$string['update_success_o365'] = 'Microsoft 365 connection record updated successfully.';
+$string['update_error_nothing_updated'] = 'Nothing was updated.';
+$string['error_invalid_upload_file'] = 'Invalid upload file.';
+$string['csvline'] = 'CSV line';
+$string['change_binding_username_claim_tool'] = 'Change binding username claim tool';
+$string['change_binding_username_claim_tool_description'] = '
+This tool allows site administrators to bulk update the following records:
+
+- Moodle account usernames,
+- Binding usernames in stored OpenID Connect ID tokens,
+- Moodle and Microsoft account connection records.
+
+This should only be used when changing the Binding username claim settings.
+Be very cautious when using this feature, and follow the steps on the Binding username claim configuration page. Misuse of this tool will result in Moodle user records being damaged and/or SSO failure.
+The tool accepts a simple CSV file with two columns:
+
+- username: The current username of the Moodle account to be updated, or if the current user is manually matched, this needs to be the current binding claim value.
+- new_username: The case-sensitive value of the new token claim to be used as the binding username claim. If the user is automatically matched and uses the OpenID Connect authentication type, the lowercase of this value will be used as Moodle username.
+
+When the file is uploaded, the tool will perform the following actions:
+
+- Find an existing Moodle user with the given username as either username or email address, and using the OpenID Connect authentication method, and if one is found, update the username of the user to be the lowercase of new_username.
+- Update OpenID Connect token record.
+
+- If a user is found in the step 1 above, then find the token record in the auth_oidc_token table for the user, and update username column to be the lowercase of new_username, and oidcusername column to be the same as new_username.
+- If no record is found above, it will try to find record in the auth_oidc_token with oidcusername column matching the old username, and update it to be newusername.
+
+ - Providing the local_365 plugin is installed, update user connection record.
+
+- If a user is found in stpe 1 above, then find the connection record of the user in the local_o365_objects table, and update the o365name column to be the same as new_username.
+- If no user is found in step 1, then it will try to find a record for a user in local_o365_objects table with o365name matching the username value, and update it to be newusername value.
+
+
+The example file below would change the binding username claim from upn or email to oid.
';
+$string['change_binding_username_claim_tool_result'] = 'Update results';
+$string['update_username_results'] = 'Update username results';
+$string['new_username'] = 'New username';
+$string['missing_idp_type'] = 'This configuration is only available if an IdP type is configured.';
+
+// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment
\ No newline at end of file
diff --git a/auth/oidc/lang/es/auth_oidc.php b/auth/oidc/lang/es/auth_oidc.php
new file mode 100644
index 00000000000..d77020ff8af
--- /dev/null
+++ b/auth/oidc/lang/es/auth_oidc.php
@@ -0,0 +1,133 @@
+.
+
+/**
+ * Spanish language strings.
+ *
+ * @package auth_oidc
+ * @author James McQuillan
+ * @author Lai Wei
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment
+
+$string['pluginname'] = 'OpenID Connect';
+$string['auth_oidcdescription'] = 'El complemento OpenID Connect ofrece funcionalidad de inicio de sesión único a través de proveedores de identidad configurables.';
+$string['cfg_authendpoint_key'] = 'Extremo de autorización';
+$string['cfg_authendpoint_desc'] = 'La URI del extremo de autorización del proveedor de identidad que va a utilizar.';
+$string['cfg_autoappend_key'] = 'Anexo automático';
+$string['cfg_autoappend_desc'] = 'Anexe automáticamente esta cadena cuando los usuarios inicien sesión mediante el flujo de inicio de sesión de nombre de usuario/contraseña. Esto es útil cuando el proveedor de identidad requiere un dominio común, pero no desea solicitar a los usuarios que lo escriban cuando inician sesión. Por ejemplo, si el usuario completo de OpenID Connect es "james@example.com" y usted escribe "@example.com" aquí, el usuario solo deberá escribir "james" como nombre de usuario.
Nota: En el caso que existan conflictos con los nombres de usuarios (es decir, un usuario de Moodle ya existe con el mismo nombre), se utiliza la prioridad del complemento de autenticación para determinar cuál de los usuarios gana.';
+$string['cfg_clientid_key'] = 'ID de cliente';
+$string['cfg_clientid_desc'] = 'Su ID de cliente registrado en el proveedor de identidad';
+$string['cfg_clientsecret_key'] = 'Secreto de cliente';
+$string['cfg_clientsecret_desc'] = 'Su secreto de cliente registrado en el proveedor de identidad. En algunos proveedores, también se conoce como clave.';
+$string['cfg_err_invalidauthendpoint'] = 'Extremo de autorización no válido';
+$string['cfg_err_invalidtokenendpoint'] = 'Extremo de ficha no válido';
+$string['cfg_err_invalidclientid'] = 'ID de cliente no válido';
+$string['cfg_err_invalidclientsecret'] = 'Secreto de cliente no válido';
+$string['cfg_icon_key'] = 'Icono';
+$string['cfg_icon_desc'] = 'Un icono para mostrar junto al nombre del proveedor en la página de inicio de sesión.';
+$string['cfg_iconalt_o365'] = 'Icono de Microsoft 365';
+$string['cfg_iconalt_locked'] = 'Icono de bloqueado';
+$string['cfg_iconalt_lock'] = 'Icono de bloqueo';
+$string['cfg_iconalt_go'] = 'Círculo verde';
+$string['cfg_iconalt_stop'] = 'Círculo rojo';
+$string['cfg_iconalt_user'] = 'Icono de usuario';
+$string['cfg_iconalt_user2'] = 'Icono de usuario alternativo';
+$string['cfg_iconalt_key'] = 'Icono de clave';
+$string['cfg_iconalt_group'] = 'Icono de grupo';
+$string['cfg_iconalt_group2'] = 'Icono de grupo alternativo';
+$string['cfg_iconalt_mnet'] = 'Icono de MNET';
+$string['cfg_iconalt_userlock'] = 'Icono de usuario con bloqueo';
+$string['cfg_iconalt_plus'] = 'Icono de Plus';
+$string['cfg_iconalt_check'] = 'Icono de marca de verificación';
+$string['cfg_iconalt_rightarrow'] = 'Icono de flecha a la derecha';
+$string['cfg_customicon_key'] = 'Icono personalizado';
+$string['cfg_customicon_desc'] = 'Si desea utilizar su propio icono, cárguelo aquí. Esto anula cualquier icono que haya elegido arriba.
Notas sobre el uso de iconos personalizados:- Esta imagen no cambiará de tamaño en la página de inicio de sesión, de manera que le recomendamos que cargue una imagen no mayor a 35x35 píxeles.
- Si cargó un icono personalizado y desea volver a algunos de los iconos preestablecidos, haga clic en el icono personalizado en el cuadro de arriba, luego haga clic en "Eliminar", luego en "Aceptar", y luego en "Guardar cambios" en la parte inferior de este formulario. El icono preestablecido seleccionado aparecerá ahora en la página de inicio de sesión de Moodle.
';
+$string['cfg_debugmode_key'] = 'Registrar mensajes de depuración';
+$string['cfg_debugmode_desc'] = 'Si está habilitado, se registrará información en el registro de Moodle que puede ayudarlo a identificar problemas.';
+$string['cfg_loginflow_key'] = 'Flujo de inicio de sesión';
+$string['cfg_loginflow_authcode'] = 'Solicitud de autorización';
+$string['cfg_loginflow_authcode_desc'] = 'Al utiliza este flujo, el usuario hace clic en el nombre del proveedor de identidad (consulte "Nombre del proveedor" más arriba) en la página de inicio de sesión de Moodle y es redireccionado al proveedor para iniciar sesión. Una vez que haya iniciado sesión correctamente, es redireccionado de vuelta a Moodle, donde se realiza el inicio de sesión de manera transparente. Esta es la forma más segura y estandarizada de inicio de sesión del usuario.';
+$string['cfg_loginflow_rocreds'] = 'Autenticación de nombre de usuario/contraseña';
+$string['cfg_loginflow_rocreds_desc'] = 'Al usar este flujo, el usuario ingresa el nombre de usuario y la contraseña al formulario de inicio de sesión de Moodle como lo haría de manera manual. Luego, las credenciales se pasan al proveedor de identidad en el segundo plano para obtener la autenticación. Este flujo es la forma más transparente para el usuario ya que no posee interacción directa con el proveedor de identidad. Tenga en cuenta que no todos los proveedores de identidad admiten este flujo.';
+$string['cfg_oidcresource_key'] = 'Recurso';
+$string['cfg_oidcresource_desc'] = 'El recurso de OpenID Connect para el cual enviar la solicitud.';
+$string['cfg_oidcscope_key'] = 'Scope';
+$string['cfg_oidcscope_desc'] = 'El alcance de OIDC a utilizar.';
+$string['cfg_opname_key'] = 'Nombre del proveedor';
+$string['cfg_opname_desc'] = 'Esta es una etiqueta que apunta al usuario final e identifica el tipo de credenciales que el usuario debe utilizar para iniciar sesión. Esta etiqueta se utiliza durante todas las partes que apuntan al usuario de este complemento para identificar al proveedor.';
+$string['cfg_redirecturi_key'] = 'URI de redireccionamiento';
+$string['cfg_redirecturi_desc'] = 'Est es la URI para registrar como "URI de redireccionamiento". Su proveedor de identidad de OpenID Connect debe solicitarla cuando registra Moodle como cliente.
NOTA: Debe ingresarla en su proveedor de OpenID Connect *exactamente* como aparece aquí. Cualquier diferencia evitará el inicio de sesión usando OpenID Connect.';
+$string['cfg_tokenendpoint_key'] = 'Extremo de ficha';
+$string['cfg_tokenendpoint_desc'] = 'La URI del extremo de ficha del proveedor de identidad que debe utilizar.';
+$string['event_debug'] = 'Mensaje de depuración';
+$string['errorauthdisconnectemptypassword'] = 'La contraseña no puede estar vacía';
+$string['errorauthdisconnectemptyusername'] = 'El nombre de usuario no puede estar vacío';
+$string['errorauthdisconnectusernameexists'] = 'Ese nombre de usuario ya está en uso. Elija uno distinto.';
+$string['errorauthdisconnectnewmethod'] = 'Usar método de inicio de sesión';
+$string['errorauthdisconnectinvalidmethod'] = 'Se recibió un método de inicio de sesión no válido.';
+$string['errorauthdisconnectifmanual'] = 'Si utiliza un método de inicio de sesión manual, ingrese las credenciales a continuación.';
+$string['errorauthinvalididtoken'] = 'Se recibió un id_token no válido.';
+$string['errorauthloginfailednouser'] = 'Inicio de sesión no válido: no se encontró el usuario en Moodle.';
+$string['errorauthnoauthcode'] = 'No se recibió el código de autenticación.';
+$string['errorauthnocreds'] = 'Configure las credenciales del cliente de OpenID Connect.';
+$string['errorauthnoendpoints'] = 'Configure los extremos del servidor de OpenID Connect.';
+$string['errorauthnohttpclient'] = 'Establezca un cliente de HTTP.';
+$string['errorauthnoidtoken'] = 'No se recibió el id_token de OpenID Connect.';
+$string['errorauthunknownstate'] = 'Estado desconocido.';
+$string['errorauthuseralreadyconnected'] = 'Ya está conectado a un usuario distinto de OpenID Connect.';
+$string['errorauthuserconnectedtodifferent'] = 'El usuario de OpenID Connect que autenticó ya está conectado al usuario de Moodle.';
+$string['errorbadloginflow'] = 'Se especificó un flujo de inicio de sesión no válido. Nota: si recibió esto después de una instalación o actualización reciente, borre el caché de Moodle.';
+$string['errorjwtbadpayload'] = 'No se pudo leer la carga de pago de JWT.';
+$string['errorjwtcouldnotreadheader'] = 'No se pudo leer el encabezado de JWT';
+$string['errorjwtempty'] = 'Se recibió un JWT vacío o que no es cadena.';
+$string['errorjwtinvalidheader'] = 'Encabezado de JWT no válido';
+$string['errorjwtmalformed'] = 'Se recibió un JWT incorrecto.';
+$string['errorjwtunsupportedalg'] = 'JWS Alg o JWE no compatible';
+$string['erroroidcnotenabled'] = 'El complemento de autenticación de OpenID Connect no está habilitado.';
+$string['errornodisconnectionauthmethod'] = 'No se puede desconectar porque no hay un complemento de autenticación habilitado para volver (el método de inicio de sesión anterior del usuario o el método de inicio de sesión manual).';
+$string['erroroidcclientinvalidendpoint'] = 'Se recibió una URI de extremo no válida.';
+$string['erroroidcclientnocreds'] = 'Establezca las credenciales del cliente con secretos';
+$string['erroroidcclientnoauthendpoint'] = 'No se configuró el extremo de autorización. Configúrelo con $this->setendpoints';
+$string['erroroidcclientnotokenendpoint'] = 'No se configuró el extremo de ficha. Configúrelo con $this->setendpoints';
+$string['erroroidcclientinsecuretokenendpoint'] = 'El extremo de ficha debe utilizar SSL/TLS para esto.';
+$string['errorucpinvalidaction'] = 'Se recibió una acción no válida.';
+$string['erroroidccall'] = 'Error en OpenID Connect. Revise los registros para obtener más información.';
+$string['erroroidccall_message'] = 'Error en OpenID Connect: {$a}';
+$string['eventuserauthed'] = 'Usuario autorizado con OpenID Connect';
+$string['eventusercreated'] = 'Usuario creado con OpenID Connect';
+$string['eventuserconnected'] = 'Usuario conectado a OpenID Connect';
+$string['eventuserloggedin'] = 'Usuario inició sesión con OpenID Connect';
+$string['eventuserdisconnected'] = 'Usuario desconectado de OpenID Connect';
+$string['oidc:manageconnection'] = 'Administrar conexión de OpenID Connect';
+$string['ucp_general_intro'] = 'Aquí puede administrar su conexión a {$a}. Si está habilitado, podrá utilizar su cuenta de {$a} para iniciar sesión en Moodle en lugar de un nombre de usuario y contraseña separados. Una vez conectado, ya no tendrá que recordar el nombre de usuario y la contraseña para Moodle, todos los inicios de sesión serán gestionados por {$a}.';
+$string['ucp_login_start'] = 'Comenzar a usar {$a} para iniciar sesión en Moodle';
+$string['ucp_login_start_desc'] = 'Esto cambiará su cuenta para usar {$a} para iniciar sesión en Moodle. Una vez habilitado, deberá iniciar sesión con sus credenciales de {$a} - su nombre de usuario y contraseña actuales de Moodle no funcionarán. Puede desconectar su cuenta en cualquier momento y volver a iniciar sesión normalmente.';
+$string['ucp_login_stop'] = 'Dejar de usar {$a} para iniciar sesión en Moodle';
+$string['ucp_login_stop_desc'] = 'Actualmente, está utilizando {$a} para iniciar sesión en Moodle. Si hace clic en "Dejar de usar el inicio de sesión de {$a}" su cuenta de Moodle se desconectará de {$a}. Ya no podrá volver a iniciar sesión en Moodle con su cuenta de {$a}. Se le solicitará que cree un nombre de usuario y una contraseña, y a partir de allí podrá volver a iniciar sesión en Moodle directamente.';
+$string['ucp_login_status'] = 'El inicio de sesión de {$a} es:';
+$string['ucp_status_enabled'] = 'Habilitado';
+$string['ucp_status_disabled'] = 'Desactivado';
+$string['ucp_disconnect_title'] = 'Desconexión de {$a}';
+$string['ucp_disconnect_details'] = 'Esto desconectará su cuenta de Moodle de {$a}. Deberá crear un nombre de usuario y una contraseña para iniciar sesión en Moodle.';
+$string['ucp_title'] = 'Administración de {$a}';
+
+// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment
\ No newline at end of file
diff --git a/auth/oidc/lang/fi/auth_oidc.php b/auth/oidc/lang/fi/auth_oidc.php
new file mode 100644
index 00000000000..272309fcf51
--- /dev/null
+++ b/auth/oidc/lang/fi/auth_oidc.php
@@ -0,0 +1,133 @@
+.
+
+/**
+ * Finnish language strings.
+ *
+ * @package auth_oidc
+ * @author James McQuillan
+ * @author Lai Wei
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment
+
+$string['pluginname'] = 'OpenID Connect';
+$string['auth_oidcdescription'] = 'OpenID Connect -lisäosa mahdollistaa kertakirjautumisen käyttämällä määritettävissä olevaa identiteetintarjoajaa.';
+$string['cfg_authendpoint_key'] = 'Todennuksen päätepiste';
+$string['cfg_authendpoint_desc'] = 'Käytettävän identiteetintarjoajan todennuksen päätepisteen URI.';
+$string['cfg_autoappend_key'] = 'Lisää automaattisesti';
+$string['cfg_autoappend_desc'] = 'Lisää tämän merkkijonon automaattisesti, kun käyttäjät käyttävät kirjautumiseen käyttäjänimi/salasana-kulkua. Tästä on hyötyä, kun identiteetintarjoaja edellyttää yhtenäistä toimialuetta, mutta et halua, että käyttäjien on kirjoitettava toimialue jokaisen kirjautumisen yhteydessä. Jos käyttäjän täydellinen OpenID Connect -käyttäjätunnus on esimerkiksi james@example.com ja kirjoitat tähän kenttään @example.com, käyttäjän tarvitsee antaa käyttäjänimeksi vain james.
Huomautus: Jos käyttäjänimissä on ristiriitoja, esimerkiksi järjestelmässä on samanniminen Moodle-käyttäjä, prioriteettijärjestys määräytyy todennuslisäosan mukaan.';
+$string['cfg_clientid_key'] = 'Asiakastunnus';
+$string['cfg_clientid_desc'] = 'Identiteetintarjoajan palveluun rekisteröity asiakastunnus.';
+$string['cfg_clientsecret_key'] = 'Asiakassalaisuus';
+$string['cfg_clientsecret_desc'] = 'Identiteetintarjoajan palveluun rekisteröity asiakassalaisuus. Joidenkin palveluntarjoajien palveluissa tätä kutsutaan avaimeksi.';
+$string['cfg_err_invalidauthendpoint'] = 'Virheellinen todennuksen päätepiste';
+$string['cfg_err_invalidtokenendpoint'] = 'Virheellinen avaimen päätepiste';
+$string['cfg_err_invalidclientid'] = 'Virheellinen asiakastunnus';
+$string['cfg_err_invalidclientsecret'] = 'Virheellinen asiakassalaisuus';
+$string['cfg_icon_key'] = 'Kuvake';
+$string['cfg_icon_desc'] = 'Kirjautumissivulla palveluntarjoajan nimen vieressä näkyvä kuvake.';
+$string['cfg_iconalt_o365'] = 'Microsoft 365 -kuvake';
+$string['cfg_iconalt_locked'] = 'Lukittu-kuvake';
+$string['cfg_iconalt_lock'] = 'Lukkokuvake';
+$string['cfg_iconalt_go'] = 'Vihreä ympyrä';
+$string['cfg_iconalt_stop'] = 'Punainen ympyrä';
+$string['cfg_iconalt_user'] = 'Käyttäjäkuvake';
+$string['cfg_iconalt_user2'] = 'Vaihtoehtoinen käyttäjäkuvake';
+$string['cfg_iconalt_key'] = 'Avainkuvake';
+$string['cfg_iconalt_group'] = 'Ryhmäkuvake';
+$string['cfg_iconalt_group2'] = 'Vaihtoehtoinen ryhmäkuvake';
+$string['cfg_iconalt_mnet'] = 'MNET-kuvake';
+$string['cfg_iconalt_userlock'] = 'Käyttäjä ja lukko -kuvake';
+$string['cfg_iconalt_plus'] = 'Pluskuvake';
+$string['cfg_iconalt_check'] = 'Valintamerkki-kuvake';
+$string['cfg_iconalt_rightarrow'] = 'Oikealle osoittava nuolikuvake';
+$string['cfg_customicon_key'] = 'Mukautettu kuvake';
+$string['cfg_customicon_desc'] = 'Jos haluat käyttää mukautettua kuvaketta, lataa se tähän. Ladattu kuvake korvaa valittuna olevan kuvakkeen.
Mukautettujen kuvakkeiden käytössä huomioitavaa:- Kuvan kokoa ei muuteta kirjautumissivulla, joten suosittelemme lataamaan kuvan, jonka koko on enintään 35 x 35 pikseliä.
- Jos olet ladannut mukautetun kuvan, mutta haluat palata käyttämään vakiokuvaketta, napsauta mukautetun kuvakkeen ruutua yllä ja valitse Poista ja sitten OK. Valitse lopuksi Tallenna muutokset tämän lomakkeen alaosassa. Valittu vakiokuvake näytetään tämän jälkeen Moodlen kirjautumissivulla.
';
+$string['cfg_debugmode_key'] = 'Kirjaa virheenkorjausviestit';
+$string['cfg_debugmode_desc'] = 'Jos asetus on käytössä, tiedot kirjataan Moodlen lokiin ongelmien tunnistamista varten.';
+$string['cfg_loginflow_key'] = 'Kirjautumiskulku';
+$string['cfg_loginflow_authcode'] = 'Valtuutuspyyntö';
+$string['cfg_loginflow_authcode_desc'] = 'Jos tämä kirjautumiskulku on käytössä, käyttäjä napsauttaa identiteetintarjoajan nimeä (ks. Palveluntarjoajan nimi) Moodlen kirjautumissivulla, jonka jälkeen käyttäjä ohjataan palveluntarjoajan sivulle kirjautumista varten. Jos kirjautuminen onnistuu, käyttäjä ohjataan takaisin Moodleen, jossa Moodle-kirjautuminen tapahtuu läpinäkyvästi. Tämä on standardisoitu ja turvallisin käyttäjien kirjautumismenetelmä.';
+$string['cfg_loginflow_rocreds'] = 'Käyttäjänimen/salasanan todennus';
+$string['cfg_loginflow_rocreds_desc'] = 'Jos tämä kirjautumiskulku on käytössä, käyttäjä kirjautuu Moodleen antamalla käyttäjänimen ja salasanan Moodlen kirjautumislomakkeeseen. Tunnistetiedot välitetään taustalla identiteetintarjoajalle todennusta varten. Tämä kulku on läpinäkyvin käyttäjän kannalta, koska käyttäjä ei ole suoraan tekemisissä identiteetintarjoajan kanssa. Huomaa, että kaikki identiteetintarjoajat eivät tue tätä kulkua.';
+$string['cfg_oidcresource_key'] = 'Resurssi';
+$string['cfg_oidcresource_desc'] = 'OpenID Connect -resurssi, jota lähetettävä pyyntö koskee.';
+$string['cfg_oidcscope_key'] = 'laajuus';
+$string['cfg_oidcscope_desc'] = 'Käytettävä OIDC-soveltamisala.';
+$string['cfg_opname_key'] = 'Palveluntarjoajan nimi';
+$string['cfg_opname_desc'] = 'Tämä on loppukäyttäjälle näkyvä selite, joka ilmoittaa kirjautumiseen käytettävien tunnistetietojen tyypin. Tätä palveluntarjoajan selitettä käytetään tämän lisäosan kaikissa käyttäjälle näkyvissä osioissa.';
+$string['cfg_redirecturi_key'] = 'Uudelleenohjauksen URI';
+$string['cfg_redirecturi_desc'] = 'Tämä on rekisteröitävä uudelleenohjauksen URI. OpenID Connect -identiteetintarjoaja pyytää tätä tietoa, kun rekisteröit Moodlen asiakkaaksi.
HUOMAUTUS: Anna URI OpenID Connect -palveluntarjoajan palveluun *täsmälleen* tässä näkyvässä muodossa. Muussa tapauksessa kirjautuminen OpenID Connect -palvelun avulla ei onnistu.';
+$string['cfg_tokenendpoint_key'] = 'Avaimen päätepiste';
+$string['cfg_tokenendpoint_desc'] = 'Käytettävän identiteetintarjoajan avaimen päätepiste.';
+$string['event_debug'] = 'Virheenkorjausviesti';
+$string['errorauthdisconnectemptypassword'] = 'Salasana ei voi olla tyhjä';
+$string['errorauthdisconnectemptyusername'] = 'Käyttäjänimi ei voi olla tyhjä';
+$string['errorauthdisconnectusernameexists'] = 'Annettu käyttäjänimi on jo käytössä. Valitse toinen nimi.';
+$string['errorauthdisconnectnewmethod'] = 'Käyttäjän kirjautumismenetelmä';
+$string['errorauthdisconnectinvalidmethod'] = 'Virheellinen kirjautumismenetelmä vastaanotettiin.';
+$string['errorauthdisconnectifmanual'] = 'Jos käytät manuaalista kirjautumismenetelmää, anna tunnistetiedot alla.';
+$string['errorauthinvalididtoken'] = 'Virheellinen id_token vastaanotettiin.';
+$string['errorauthloginfailednouser'] = 'Kirjautumisvirhe: käyttäjää ei löydy Moodlesta.';
+$string['errorauthnoauthcode'] = 'Todennuskoodia ei vastaanotettu.';
+$string['errorauthnocreds'] = 'Määritä OpenID Connect -asiakkaan tunnistetiedot.';
+$string['errorauthnoendpoints'] = 'Määritä OpenID Connect -palvelimen päätepisteet.';
+$string['errorauthnohttpclient'] = 'Määritä HTTP-asiakas.';
+$string['errorauthnoidtoken'] = 'OpenID Connectin id_token-avainta ei vastaanotettu.';
+$string['errorauthunknownstate'] = 'Tuntematon tila.';
+$string['errorauthuseralreadyconnected'] = 'Yhteys on jo muodostettu toiseen OpenID Connect -käyttäjään.';
+$string['errorauthuserconnectedtodifferent'] = 'Todennettu OpenID Connect -käyttäjä on jo yhdistetty Moodle-käyttäjään.';
+$string['errorbadloginflow'] = 'Määritetty kirjautumiskulku on virheellinen. Huomautus: Jos saat tämän viestin asennuksen tai päivityksen jälkeen, tyhjennä Moodlen välimuisti.';
+$string['errorjwtbadpayload'] = 'JWT-tietoja ei voitu lukea.';
+$string['errorjwtcouldnotreadheader'] = 'JWT-otsikkoa ei voitu lukea';
+$string['errorjwtempty'] = 'Vastaanotettu JWT on tyhjä, tai se ei ole kelvollinen merkkijono.';
+$string['errorjwtinvalidheader'] = 'Virheellinen JWT-otsikko';
+$string['errorjwtmalformed'] = 'Vastaanotettu JWT on virheellinen.';
+$string['errorjwtunsupportedalg'] = 'JWS Alg tai JWE ei ole tuettu';
+$string['erroroidcnotenabled'] = 'OpenID Connect -todennuslisäosa ei ole käytössä.';
+$string['errornodisconnectionauthmethod'] = 'Yhteyttä ei voi katkaista, koska vaihtoehtoista todennuslisäosaa ei ole määritetty (se voi olla käyttäjän edellinen kirjautumismenetelmä tai manuaalinen kirjautumismenetelmä).';
+$string['erroroidcclientinvalidendpoint'] = 'Virheellinen pääpisteen URI vastaanotettiin.';
+$string['erroroidcclientnocreds'] = 'Määritä asiakkaan tunnistetiedot setcreds-komennolla';
+$string['erroroidcclientnoauthendpoint'] = 'Todennuksen päätepistettä ei ole määritetty. Määritä komennolla $this->setendpoints';
+$string['erroroidcclientnotokenendpoint'] = 'Avaimen päätepistettä ei ole määritetty. Määritä komennolla $this->setendpoints';
+$string['erroroidcclientinsecuretokenendpoint'] = 'Avaimen päätepisteen on käytettävä tähän SSL/TLS-yhteyttä.';
+$string['errorucpinvalidaction'] = 'Virheellinen toiminto vastaanotettiin.';
+$string['erroroidccall'] = 'OpenID Connect -palvelussa tapahtui virhe. Lisätietoja on lokeissa.';
+$string['erroroidccall_message'] = 'Virhe OpenID Connect -palvelussa: {$a}';
+$string['eventuserauthed'] = 'Käyttäjä valtuutettiin OpenID Connectin avulla';
+$string['eventusercreated'] = 'Käyttäjä luotiin OpenID Connectin avulla';
+$string['eventuserconnected'] = 'Käyttäjä yhdistettiin OpenID Connectin avulla';
+$string['eventuserloggedin'] = 'Käyttäjä kirjautui OpenID Connectin avulla';
+$string['eventuserdisconnected'] = 'Käyttäjän OpenID Connect -yhteys katkaistiin';
+$string['oidc:manageconnection'] = 'OpenID Connect -yhteyden hallinta';
+$string['ucp_general_intro'] = 'Tässä kohdassa voit hallita {$a} -yhteyttä. Jos asetus on käytössä, voit kirjautua Moodleen käyttämällä {$a} -tiliäsi erillisen käyttäjänimen ja salasanan sijaan. Kun yhteys on luotu, sinun ei tarvitse muistaa Moodle-käyttäjänimeä ja -salasanaa, koska {$a} huolehtii kirjautumisesta.';
+$string['ucp_login_start'] = 'Aloita palvelun {$a} käyttö Moodle-kirjautumiseen';
+$string['ucp_login_start_desc'] = 'Voit käyttää {$a} -tiliäsi Moodle-kirjautumiseen. Kun asetus on käytössä, kirjaudut Moodleen käyttämällä {$a} -tunnistetietojasi. Nykyinen Moodle-käyttäjänimi ja -salasana eivät enää toimi. Voit katkaista tilisi yhteyden milloin tahansa ja palata käyttämään normaalia kirjautumista.';
+$string['ucp_login_stop'] = 'Lopeta palvelun {$a} käyttö Moodle-kirjautumiseen';
+$string['ucp_login_stop_desc'] = '{$a} on tällä hetkellä käytössä Moodle-kirjautumiseen. Jos valitset Lopeta palvelun {$a} käyttö -asetuksen, Moodle-tilin yhteys palveluun {$a} katkaistaan. Tämän jälkeen et voi kirjautua Moodleen käyttämällä {$a} -tiliäsi. Sinua pyydetään luomaan käyttäjänimi ja salasana, joiden avulla voit kirjautua suoraan Moodleen.';
+$string['ucp_login_status'] = '{$a} -kirjautuminen:';
+$string['ucp_status_enabled'] = 'Käytössä';
+$string['ucp_status_disabled'] = 'Ei käytössä';
+$string['ucp_disconnect_title'] = '{$a} -yhteyden katkaisu';
+$string['ucp_disconnect_details'] = 'Tämä katkaisee Moodle-tilin yhteyden kohteesta {$a}. Tarvitset käyttäjänimen ja salasanan, jotta voit kirjautua Moodleen.';
+$string['ucp_title'] = '{$a} -hallinta';
+
+// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment
\ No newline at end of file
diff --git a/auth/oidc/lang/fr/auth_oidc.php b/auth/oidc/lang/fr/auth_oidc.php
new file mode 100644
index 00000000000..885f66c9162
--- /dev/null
+++ b/auth/oidc/lang/fr/auth_oidc.php
@@ -0,0 +1,169 @@
+.
+
+/**
+ * French language strings.
+ *
+ * @package auth_oidc
+ * @author James McQuillan
+ * @author Lai Wei
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment
+
+$string['pluginname'] = 'OpenID Connect';
+$string['auth_oidcdescription'] = 'Le plug-in OpenID Connect fournit une fonctionnalité SSO avec des fournisseurs d\'identité configurables.';
+
+$string['cfg_authendpoint_key'] = 'Point d\'accès d\'autorisation';
+$string['cfg_authendpoint_desc'] = 'URI du point d\'accès d\'autorisation de votre fournisseur d\'identité à utiliser.';
+$string['cfg_autoappend_key'] = 'Ajout automatique';
+$string['cfg_autoappend_desc'] = 'Ajoutez automatiquement cette chaîne lors de la connexion d\'utilisateurs utilisant la méthode d\'authentification "Nom d\'utilisateur/mot de passe". Cette opération est utile lorsque votre fournisseur d\'identité nécessite un domaine courant, mais ne souhaite pas exiger aux utilisateurs de le saisir lors de la connexion. Par exemple, si l\'utilisateur OpenID Connect complet est « james@exemple.com » et que vous saisissez « @exemple.com » ici, l\'utilisateur n\'a qu\'à saisir « james » comme nom d\'utilisateur.
Remarque : en cas de conflit entre les noms d\'utilisateur, par exemple s\'il existe un utilisateur Moodle du même nom, la priorité du plug-in d\'authentification permet de déterminer l\'utilisateur qui l\'emporte.';
+$string['cfg_clientid_key'] = 'ID client';
+$string['cfg_clientid_desc'] = 'Votre ID client enregistré sur le fournisseur d\'identité.';
+$string['cfg_clientsecret_key'] = 'Secret client';
+$string['cfg_clientsecret_desc'] = 'Votre secret client enregistré sur le fournisseur d\'identité. Sur certains fournisseurs, il est également appelé clé.';
+$string['cfg_domainhint_key'] = 'Domaine de l\'utilisateur';
+$string['cfg_domainhint_desc'] = 'Lorsque la méthode d\'authentification "Demande d\'autorisation" est utilisée, passez cette valeur pour le paramètre "domain_hint". "domain_hint" est utilisé par certains fournisseurs OpenID Connect pour rendre le processus de connection plus simple pour les utilisateurs. Vérifiez avec votre fournisseur s\'il supporte ce paramètre.';
+$string['cfg_err_invalidauthendpoint'] = 'Point d\'accès d\'autorisation non valide';
+$string['cfg_err_invalidtokenendpoint'] = 'Point d\'accès de jeton non valide';
+$string['cfg_err_invalidclientid'] = 'ID client non valide';
+$string['cfg_err_invalidclientsecret'] = 'Secret client non valide';
+$string['cfg_icon_key'] = 'Icône';
+$string['cfg_icon_desc'] = 'Icône à afficher près du nom de fournisseur sur la page de connexion.';
+$string['cfg_iconalt_o365'] = 'Icône Microsoft 365';
+$string['cfg_iconalt_locked'] = 'Icône verrouillée';
+$string['cfg_iconalt_lock'] = 'Icône de verrouillage';
+$string['cfg_iconalt_go'] = 'Cercle vert';
+$string['cfg_iconalt_stop'] = 'Cercle rouge';
+$string['cfg_iconalt_user'] = 'Icône utilisateur';
+$string['cfg_iconalt_user2'] = 'Autre icône utilisateur';
+$string['cfg_iconalt_key'] = 'Icône de clé';
+$string['cfg_iconalt_group'] = 'Icône de groupe';
+$string['cfg_iconalt_group2'] = 'Autre icône de groupe';
+$string['cfg_iconalt_mnet'] = 'Icône MNET';
+$string['cfg_iconalt_userlock'] = 'Utilisateur avec icône de verrouillage';
+$string['cfg_iconalt_plus'] = 'Icône Plus';
+$string['cfg_iconalt_check'] = 'Icône de coche';
+$string['cfg_iconalt_rightarrow'] = 'Icône de flèche pointant vers la droite';
+$string['cfg_customicon_key'] = 'Icône personnalisée';
+$string['cfg_customicon_desc'] = 'Si vous souhaitez utiliser votre propre icône, téléchargez-la ici. Cette opération remplace toute icône choisie ci-dessus.
Remarques sur l\'utilisation des icônes personnalisées :- cette image ne sera pas redimensionnée sur la page de connexion. Nous recommandons donc de télécharger une image de 35x35 pixels maximum.
- Si vous avez téléchargé une icône personnalisée et que vous souhaitez revenir à l\'une des icônes de stockage, cliquez sur l\'icône personnalisée dans la zone ci-dessus, puis cliquez sur « Supprimer », puis sur « OK », puis cliquez sur « Enregistrer des modifications » en bas de ce formulaire. L\'icône de stockage sélectionnée apparaît maintenant sur la page de connexion Moodle.
';
+$string['cfg_debugmode_key'] = 'Enregistrer les messages de débogage';
+$string['cfg_debugmode_desc'] = 'Si ce réglage est activé, les informations seront enregistrées dans le journal Moodle, cela peut aider à identifier les problèmes.';
+$string['cfg_loginflow_key'] = 'Méthode d\'authentification';
+$string['cfg_loginflow_authcode'] = 'Demande d\'autorisation (recommandée)';
+$string['cfg_loginflow_authcode_desc'] = 'À l\'aide de cette méthode, l\'utilisateur clique sur le fournisseur d\'identité (voir « Nom du fournisseur » ci-dessus) sur la page de connexion Moodle et est redirigé vers le fournisseur pour se connecter. Une fois la connexion réussie, l\'utilisateur est redirigé vers Moodle où la connexion Moodle est effectuée en toute transparence. Il s\'agit pour l\'utilisateur du moyen le plus sécurisé et standardisé pour se connecter.';
+$string['cfg_loginflow_rocreds'] = 'Authentification via nom d\'utilisateur/mot de passe';
+$string['cfg_loginflow_rocreds_desc'] = 'À l\'aide de cette méthode, l\'utilisateur saisit son nom d\'utilisateur et son mot de passe dans le formulaire de connexion Moodle comme il le ferait avec une connexion manuelle. Ses informations d\'identification sont ensuite transmises au fournisseur d\'identité en arrière-plan pour obtenir son authentification. Cette méthode est la plus transparente pour l\'utilisateur car il n\'a aucune interaction directe avec le fournisseur d\'identité. Notez que l\'ensemble des fournisseurs d\'identité prennent en charge ce flux.';
+$string['cfg_oidcresource_key'] = 'Ressource';
+$string['cfg_oidcresource_desc'] = 'Ressource OpenID Connect pour laquelle envoyer la demande.';
+$string['cfg_oidcscope_key'] = 'Porté';
+$string['cfg_oidcscope_desc'] = 'L\'étendue OIDC à utiliser.';
+$string['cfg_opname_key'] = 'Nom du fournisseur';
+$string['cfg_opname_desc'] = 'Il s\'agit d\'une étiquette destinée à l\'utilisateur final qui identifie le type d\'informations d\'identification dont l\'utilisateur doit se servir pour se connecter. Cette étiquette est utilisée sur toutes les sections permettant d\'identifier votre fournisseur et qui sont visibles par l\'utilisateur.';
+$string['cfg_redirecturi_key'] = 'URI de redirection';
+$string['cfg_redirecturi_desc'] = 'URI à enregistrer comme « URI de redirection ». Votre fournisseur d\'identité OpenID Connect doit demander cet URI lors de l\'enregistrement de Moodle comme client.
REMARQUE : vous devez entrer cet URI dans votre fournisseur OpenID Connect *exactement* tel qu\'il apparaît ici. La moindre différence empêchera les connexions d\'utiliser OpenID Connect.';
+$string['cfg_tokenendpoint_key'] = 'Point d\'accès de jeton';
+$string['cfg_tokenendpoint_desc'] = 'URI du point d\'accès de jeton de votre fournisseur d\'identité à utiliser.';
+$string['cfg_userrestrictions_key'] = 'Restrictions utilisateur';
+$string['cfg_userrestrictions_desc'] = 'Ne permettre qu\'aux utilisateurs correspondant à certains critères de se connecter.
Comment utiliser les restrictions d\'utilisateurs : - Entrez une expression régulière correspondant aux noms d\'utilisateurs des utilisateurs que vous souhaitez autoriser.
- Entrez une expression par ligne
- Si vous entrez plusieurs expressions, l\'utilisateur sera autorisé s\'il correspond à N\'IMPORTE LAQUELLE des expressions.
- Le caractère "/" doit être précédé de "\".
- Si vous n\'entrez aucune restriction ci-dessus, tous les utilisateurs pouvant se connecter au fournisseur OpenID Connect seront acceptés par Moodle.
- Tout utilisateur ne correspondant à aucune des expressions entrées ne pourra pas se connecter à l\'aide d\'OpenID Connect.
';
+$string['event_debug'] = 'Message de débogage';
+
+$string['errorauthdisconnectemptypassword'] = 'Le mot de passe ne peut pas être vide';
+$string['errorauthdisconnectemptyusername'] = 'Le nom d\'utilisateur ne peut pas être vide';
+$string['errorauthdisconnectusernameexists'] = 'Ce nom d\'utilisateur est déjà attribué. Choisissez-en un autre.';
+$string['errorauthdisconnectnewmethod'] = 'Utiliser une méthode de connexion';
+$string['errorauthdisconnectinvalidmethod'] = 'Méthode de connexion non valide reçue.';
+$string['errorauthdisconnectifmanual'] = 'Si vous utilisez la méthode de connexion manuelle, saisissez les informations d\'identification ci-dessous.';
+$string['errorauthgeneral'] = 'Il y a eu un problème lors de votre connexion. Veuillez contacter votre administrateur pour de l\'aide.';
+$string['errorauthinvalididtoken'] = 'id_token reçu non valide.';
+$string['errorauthloginfailednouser'] = 'Connexion non valide : utilisateur introuvable dans Moodle. Si le paramètre "authpreventaccountcreation" est activé sur ce site, cela peut signifier que vous avez besoin d\'un administrateur pour vous créer un compte.';
+$string['errorauthnoauthcode'] = 'Code d\'authentification non reçu. Les journaux d\'erreurs peuvent contenir plus d\'informations.';
+$string['errorauthnocreds'] = 'Configurez les informations d\'identification du client OpenID Connect.';
+$string['errorauthnoendpoints'] = 'Configurez les points d\'accès du serveur OpenID Connect.';
+$string['errorauthnohttpclient'] = 'Définissez un client HTTP.';
+$string['errorauthnoidtoken'] = 'Jeton OpenID Connect id_token non reçu.';
+$string['errorauthunknownstate'] = 'État inconnu.';
+$string['errorauthuseralreadyconnected'] = 'Vous êtes déjà connecté à un autre utilisateur OpenID Connect.';
+$string['errorauthuserconnectedtodifferent'] = 'L\'utilisateur OpenID Connect qui s\'est authentifié est déjà connecté à un utilisateur Moodle.';
+$string['errorbadloginflow'] = 'Méthode d\'authentification spécifiée non valide. Remarque : si vous recevez ce message après une installation ou une mise à niveau récente, effacez votre cache Moodle.';
+$string['errorjwtbadpayload'] = 'Impossible de lire la charge JWT.';
+$string['errorjwtcouldnotreadheader'] = 'Impossible de lire l\'en-tête JWT';
+$string['errorjwtempty'] = 'JWT vide ou sans chaîne reçu.';
+$string['errorjwtinvalidheader'] = 'En-tête JWT non valide';
+$string['errorjwtmalformed'] = 'JWT malformé reçu.';
+$string['errorjwtunsupportedalg'] = 'JWS Alg ou JWE non pris en charge';
+$string['errorlogintoconnectedaccount'] = 'Cet utilisateur Microsoft 365 est associé à un utilisateur Moodle, mais la connexion via OpenID Connect n\'est pas activée pour cet utilisateur Moodle. Veuillez vous connecter à Moodle en utilisant la méthode d\'authentification définie dans le compte de l\'utilisateur afin d\'utiliser les fonctionnalités Microsoft 365';
+$string['erroroidcnotenabled'] = 'Le plug-in d\'authentification OpenID Connect n\'est pas activé.';
+$string['errornodisconnectionauthmethod'] = 'Déconnexion impossible en l\'absence de plug-in d\'autorisation activé vers lequel se rabattre (soit la méthode de connexion précédente de l\'utilisateur, soit la méthode de connexion manuelle).';
+$string['erroroidcclientinvalidendpoint'] = 'URI du point d\'accès non valide reçu.';
+$string['erroroidcclientnocreds'] = 'Définissez les informations d\'identification client avec setcreds';
+$string['erroroidcclientnoauthendpoint'] = 'Aucun point d\'accès d\'autorisation défini. Définissez-le avec $this->setendpoints';
+$string['erroroidcclientnotokenendpoint'] = 'Aucun point d\'accès de jeton défini. Définissez-le avec $this->setendpoints';
+$string['erroroidcclientinsecuretokenendpoint'] = 'Le point d\'accès de jeton doit utiliser SSL/TLS.';
+$string['errorrestricted'] = 'Ce site impose des restrictions quant aux utilisateurs pouvant se connecter avec OpenID Connect. Ces restrictions vous empêchent actuellement de vous connecter.';
+$string['errorucpinvalidaction'] = 'Action non valide reçue.';
+$string['erroroidccall'] = 'Erreur dans OpenID Connect. Pour plus d\'informations, consultez les journaux d\'erreurs.';
+$string['erroroidccall_message'] = 'Erreur dans OpenID Connect : {$a}';
+$string['errorinvalidredirect_message'] = 'L\'URL à laquelle vous tentez de vous rediriger n\'existe pas.';
+
+$string['eventuserauthed'] = 'Utilisateur autorisé avec OpenID Connect';
+$string['eventusercreated'] = 'Utilisateur créé avec OpenID Connect';
+$string['eventuserconnected'] = 'Utilisateur connecté à OpenID Connect';
+$string['eventuserloggedin'] = 'Utilisateur identifié avec OpenID Connect';
+$string['eventuserdisconnected'] = 'Utilisateur déconnecté d\'OpenID Connect';
+
+$string['oidc:manageconnection'] = 'Permettre la connexion et la déconnexion OpenID';
+$string['oidc:manageconnectionconnect'] = 'Permettre la connexion OpenID';
+$string['oidc:manageconnectiondisconnect'] = 'Permettre la déconnexion OpenID';
+
+$string['privacy:metadata:auth_oidc'] = 'Authentification OpenID Connect';
+$string['privacy:metadata:auth_oidc_prevlogin'] = 'Méthodes de connexion précédentes pour annuler les connexions Microsoft 365';
+$string['privacy:metadata:auth_oidc_prevlogin:userid'] = 'L\'identifiant de l\'utilisateur Moodle';
+$string['privacy:metadata:auth_oidc_prevlogin:method'] = 'La méthode de connexion précédente';
+$string['privacy:metadata:auth_oidc_prevlogin:password'] = 'Le mot de passe précédent de l\'utilisateur (chiffré)';
+$string['privacy:metadata:auth_oidc_token'] = 'Jetons OpenID Connect';
+$string['privacy:metadata:auth_oidc_token:oidcuniqid'] = 'L\'identifiant utilisateur unique de OIDCs';
+$string['privacy:metadata:auth_oidc_token:username'] = 'Le nom d\'utilisateur de l\'utilisateur Moodle';
+$string['privacy:metadata:auth_oidc_token:userid'] = 'Le ID de l\'utilisateur Moodle';
+$string['privacy:metadata:auth_oidc_token:oidcusername'] = 'Le nom d\'utilisateur de l\'utilisateur OIDC';
+$string['privacy:metadata:auth_oidc_token:scope'] = 'La portée du jeton';
+$string['privacy:metadata:auth_oidc_token:tokenresource'] = 'La ressource du jeton';
+$string['privacy:metadata:auth_oidc_token:authcode'] = 'Le code d\'authentification du jeton';
+$string['privacy:metadata:auth_oidc_token:token'] = 'Le jeton';
+$string['privacy:metadata:auth_oidc_token:expiry'] = 'L\'expiration du jeton';
+$string['privacy:metadata:auth_oidc_token:refreshtoken'] = 'Le jeton de rafraîchissement';
+$string['privacy:metadata:auth_oidc_token:idtoken'] = 'Le jeton ID';
+
+// Dans les chaînes suivantes, $a réfère à un nom personnalisable pour le gestionnaire d'identité. Par exemple, ce pourrait être
+// "Microsoft 365", "OpenID Connect", etc.
+$string['ucp_general_intro'] = 'Vous pouvez gérer votre connexion à {$a} ici. Si ce réglage est activé, vous pourrez voir votre compte {$a} pour vous connecter à Moodle au lieu d\'un nom d\'utilisateur et d\'un mot de passe distincts. Une fois connecté, vous n\'aurez plus à mémoriser votre nom d\'utilisateur et votre mot de passe pour Moodle ; toutes les connexions seront gérées par {$a}.';
+$string['ucp_login_start'] = 'Commencer à utiliser {$a} pour se connecter à Moodle';
+$string['ucp_login_start_desc'] = 'Votre compte passera à {$a} pour la connexion à Moodle. Une fois ce réglage activé, vous vous connecterez à l\'aide de vos informations d\'identification {$a} (votre mot de passe et votre nom d\'utilisateur Moodle actuels ne fonctionneront pas). Vous pouvez vous déconnecter de votre compte à tout moment et utiliser de nouveau la méthode d\'authentification habituelle Moodle.';
+$string['ucp_login_stop'] = 'Cesser d\'utiliser {$a} pour se connecter à Moodle';
+$string['ucp_login_stop_desc'] = 'Vous utilisez actuellement {$a} pour vous connecter à Moodle. Cliquez sur « Cesser d\'utiliser la connexion {$a} » pour déconnecter votre compte Moodle de {$a}. Vous ne pourrez plus vous connecter à Moodle avec votre compte {$a}. Vous serez invité à créer un nom d\'utilisateur et un mot de passe, et vous pourrez ensuite vous connecter directement à Moodle.';
+$string['ucp_login_status'] = 'Connexion {$a} :';
+$string['ucp_status_enabled'] = 'Activé';
+$string['ucp_status_disabled'] = 'Désactivé';
+$string['ucp_disconnect_title'] = 'Déconnexion {$a}';
+$string['ucp_disconnect_details'] = 'Cette opération déconnectera votre compte Moodle de {$a}. Vous aurez besoin de créer un nom d\'utilisateur et un mot de passe pour vous connecter à Moodle.';
+$string['ucp_title'] = 'Gestion de {$a}';
+$string['ucp_o365accountconnected'] = 'Ce compte Microsoft 365 est déjà associé à un autre compte Moodle.';
+
+// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment
\ No newline at end of file
diff --git a/auth/oidc/lang/it/auth_oidc.php b/auth/oidc/lang/it/auth_oidc.php
new file mode 100644
index 00000000000..eed12857267
--- /dev/null
+++ b/auth/oidc/lang/it/auth_oidc.php
@@ -0,0 +1,133 @@
+.
+
+/**
+ * Italian language strings.
+ *
+ * @package auth_oidc
+ * @author James McQuillan
+ * @author Lai Wei
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment
+
+$string['pluginname'] = 'OpenID Connect';
+$string['auth_oidcdescription'] = 'Il plugin OpenID Connect fornisce funzionalità single-sign-on utilizzando Identity Provider configurabili.';
+$string['cfg_authendpoint_key'] = 'Endpoint di autorizzazione';
+$string['cfg_authendpoint_desc'] = 'L\'URI dell\'endpoint di autorizzazione dall\'Identity Provider da utilizzare.';
+$string['cfg_autoappend_key'] = 'Aggiungi automaticamente';
+$string['cfg_autoappend_desc'] = 'Aggiunge automaticamente questa stringa durante il login di utenti utilizzando il flusso di login Nome utente/Password. È utile quando l\'Identity Provider richiede un dominio comune senza però richiederne l\'inserimento durante il login. Ad esempio, se l\'utente OpenID Connect completo è "james@example.com" e si inserisce "@example.com", l\'utente deve inserire solo "james" come nome utente.
Nota: in caso di conflitto tra nomi utente, ovvero quando esiste un utente Moodle con lo stesso nome, la priorità del plugin di autenticazione è utilizzata per determinare quale utente ha la meglio.';
+$string['cfg_clientid_key'] = 'ID cliente';
+$string['cfg_clientid_desc'] = 'Il tuo ID cliente registrato sull\'Identity Provider.';
+$string['cfg_clientsecret_key'] = 'Segreto cliente';
+$string['cfg_clientsecret_desc'] = 'Il tuo segreto cliente registrato sull\'Identity Provider. Su alcuni provider, viene anche indicato come chiave.';
+$string['cfg_err_invalidauthendpoint'] = 'Endpoint di autorizzazione non valido';
+$string['cfg_err_invalidtokenendpoint'] = 'Endpoint token non valido';
+$string['cfg_err_invalidclientid'] = 'ID cliente non valido';
+$string['cfg_err_invalidclientsecret'] = 'Segreto cliente non valido';
+$string['cfg_icon_key'] = 'Icona';
+$string['cfg_icon_desc'] = 'Un\'icona visualizzata accanto al nome del provider sulla pagina di login.';
+$string['cfg_iconalt_o365'] = 'Icona Microsoft 365';
+$string['cfg_iconalt_locked'] = 'Icona Bloccato';
+$string['cfg_iconalt_lock'] = 'Icona blocca';
+$string['cfg_iconalt_go'] = 'Cerchio verde';
+$string['cfg_iconalt_stop'] = 'Cerchio rosso';
+$string['cfg_iconalt_user'] = 'Icona utente';
+$string['cfg_iconalt_user2'] = 'Icona utente alternativa';
+$string['cfg_iconalt_key'] = 'Icona chiave';
+$string['cfg_iconalt_group'] = 'Icona gruppo';
+$string['cfg_iconalt_group2'] = 'Icona gruppo alternativa';
+$string['cfg_iconalt_mnet'] = 'Icona MNET';
+$string['cfg_iconalt_userlock'] = 'Utente con icona blocco';
+$string['cfg_iconalt_plus'] = 'Icona più';
+$string['cfg_iconalt_check'] = 'Icona segno di spunta';
+$string['cfg_iconalt_rightarrow'] = 'Icona freccia verso destra';
+$string['cfg_customicon_key'] = 'Icona personalizzato';
+$string['cfg_customicon_desc'] = 'Se desideri utilizzare la tua icona, caricala qui. Questa ha la precedenza su qualsiasi icona scelta in precedenza.
Note sull\'utilizzo di icone personalizzate:- Questa immagine non verrà ridimensionata sulla pagina di login, pertanto si consiglia di caricare un\'immagine di dimensioni inferiori a 35x35 pixel.
- Se hai caricato un\'icona personalizzata e desideri tornare a una delle icone di origine, fai clic sull\'icona personalizzata nella casella precedente, scegli "Elimina", fai clic su "OK", quindi su "Salva modifiche" nella parte inferiore di questo modulo. L\'icona di origine selezionata verrà visualizzata nella pagina di login di Moodle.
';
+$string['cfg_debugmode_key'] = 'Registra messaggi di debug';
+$string['cfg_debugmode_desc'] = 'Abilitando questa opzione, le informazioni verranno registrate nel log di Moodle per risolvere problemi di identificazione.';
+$string['cfg_loginflow_key'] = 'Flusso di login';
+$string['cfg_loginflow_authcode'] = 'Richiesta di autorizzazione';
+$string['cfg_loginflow_authcode_desc'] = 'Utilizzando questo flusso, l\'utente fa clic sul nome dell\'Identity Provider (vedere "Nome provider" in precedenza) nella pagina login di Moodle e viene reindirizzato al provider per il login. Dopo il login, l\'utente viene nuovamente reindirizzato in Moodle dove il login a Moodle viene eseguito in maniera trasparente. Questo è il metodo di login più standardizzato e sicuro.';
+$string['cfg_loginflow_rocreds'] = 'Autenticazione nome utente/password';
+$string['cfg_loginflow_rocreds_desc'] = 'Utilizzando questo flusso, l\'utente inserisce il nome utente e la password nel modulo di login di Moodle seguendo la stessa procedura del login manuale. Le credenziali vengono quindi passate all\'Identity Provider in background per ottenere l\'autenticazione. Questo flusso è quello più trasparente per l\'utente in quanto non esiste interazione diretta con l\'Identity Provider. Osservare che non tutti gli Identity Provider supportano questo flusso.';
+$string['cfg_oidcresource_key'] = 'Risorsa';
+$string['cfg_oidcresource_desc'] = 'La risorsa OpenID Connect per la quale inviare la richiesta.';
+$string['cfg_oidcscope_key'] = 'Scopo';
+$string['cfg_oidcscope_desc'] = 'L\'ambito OIDC da utilizzare.';
+$string['cfg_opname_key'] = 'Nome del provider';
+$string['cfg_opname_desc'] = 'Si tratta di un\'etichetta presentata all\'utente finale che identifica il tipo di credenziali che l\'utente deve utilizzare per eseguire il login. Questa etichetta viene utilizzata in tutta la parte rivolta all\'utente del plugin per identificare il provider.';
+$string['cfg_redirecturi_key'] = 'URI di reindirizzamento';
+$string['cfg_redirecturi_desc'] = 'Si tratta dell\'URI da registrare come "URI di reindirizzamento". L\'Identity Provider di OpenID Connect deve richiedere questa informazione durante la registrazione come client.
NOTA: devi immettere questa informazione nell\'apposito campo *esattamente* come appare qui. Qualsiasi differenza non consentirà di accedere con OpenID Connect.';
+$string['cfg_tokenendpoint_key'] = 'Endpoint token';
+$string['cfg_tokenendpoint_desc'] = 'L\'URI dell\'endpoint token dall\'Identity Provider.';
+$string['event_debug'] = 'Messaggio di debug';
+$string['errorauthdisconnectemptypassword'] = 'La password non può essere vuota';
+$string['errorauthdisconnectemptyusername'] = 'Il nome utente non può essere vuoto';
+$string['errorauthdisconnectusernameexists'] = 'Questo nome utente è già impegnato. Sceglierne uno diverso.';
+$string['errorauthdisconnectnewmethod'] = 'Utilizza metodo di login';
+$string['errorauthdisconnectinvalidmethod'] = 'Ricevuto metodo di login non valido.';
+$string['errorauthdisconnectifmanual'] = 'Se si utilizza il metodo di login manuale, immettere le credenziali sottostanti.';
+$string['errorauthinvalididtoken'] = 'id_token non valido ricevuto.';
+$string['errorauthloginfailednouser'] = 'Login non valido: utente non trovato in Moodle.';
+$string['errorauthnoauthcode'] = 'Codice di autenticazione non ricevuto.';
+$string['errorauthnocreds'] = 'Configurare le credenziali cliente OpenID Connect.';
+$string['errorauthnoendpoints'] = 'Configurare gli endpoint server OpenID Connect.';
+$string['errorauthnohttpclient'] = 'Impostare un client HTTP.';
+$string['errorauthnoidtoken'] = 'OpenID Connect id_token non ricevuto.';
+$string['errorauthunknownstate'] = 'Stato sconosciuto.';
+$string['errorauthuseralreadyconnected'] = 'Sei già connesso a un utente OpenID Connect diverso.';
+$string['errorauthuserconnectedtodifferent'] = 'L\'utente OpenID Connect autenticato è già connesso a un utente Moodle.';
+$string['errorbadloginflow'] = 'Specificato flusso di login non valido. Nota: se stai ricevendo questo messaggio dopo un\'installazione o aggiornamento recente, cancella la cache Moodle.';
+$string['errorjwtbadpayload'] = 'Impossibile leggere payload JWT.';
+$string['errorjwtcouldnotreadheader'] = 'Impossibile leggere intestazione JWT';
+$string['errorjwtempty'] = 'Ricevuto JWT vuoto o di tipo non stringa.';
+$string['errorjwtinvalidheader'] = 'Intestazione JWT non valida';
+$string['errorjwtmalformed'] = 'Ricevuto JWT danneggiato.';
+$string['errorjwtunsupportedalg'] = 'JWS Alg o JWE non supportato';
+$string['erroroidcnotenabled'] = 'Il plugin di autenticazione OpenID Connect non è abilitato.';
+$string['errornodisconnectionauthmethod'] = 'Impossibile disconnettersi perché non esiste un plugin di autenticazione abilitato verso cui eseguire il fallback (metodo di accesso precedente dell\'utente o metodo di accesso manuale).';
+$string['erroroidcclientinvalidendpoint'] = 'Ricevuto URI endpoint non valido.';
+$string['erroroidcclientnocreds'] = 'Impostare credenziali cliente con segreti';
+$string['erroroidcclientnoauthendpoint'] = 'Nessun endpoint di autorizzazione impostato. Impostarlo con $this->setendpoints';
+$string['erroroidcclientnotokenendpoint'] = 'Nessun endpoint token impostato. Impostare con $this->setendpoints';
+$string['erroroidcclientinsecuretokenendpoint'] = 'L\'endpoint token deve utilizzare SSL/TLS.';
+$string['errorucpinvalidaction'] = 'Ricevuta azione non valida.';
+$string['erroroidccall'] = 'Si è verificato un errore in OpenID Connect. Consultare i log per ulteriori informazioni.';
+$string['erroroidccall_message'] = 'Si è verificato un errore in OpenID Connect: {$a}';
+$string['eventuserauthed'] = 'Utente autorizzato con OpenID Connect';
+$string['eventusercreated'] = 'Utente creato con OpenID Connect';
+$string['eventuserconnected'] = 'Utente connesso a OpenID Connect';
+$string['eventuserloggedin'] = 'Utente autenticato con OpenID Connect';
+$string['eventuserdisconnected'] = 'Utente disconnesso da OpenID Connect';
+$string['oidc:manageconnection'] = 'Gestisci connessione OpenID Connect';
+$string['ucp_general_intro'] = 'Qui puoi gestire la connessione a {$a}. Abilitando questa opzione, sarai in grado di utilizzare il tuo account {$a} per accedere a Moodle anziché un nome utente e una password separati. Dopo la connessione, non dovrai più ricordare il nome utente e la password per Moodle, tutti i login verranno gestiti da {$a}.';
+$string['ucp_login_start'] = 'Inizia a utilizzare {$a} per accedere a Moodle';
+$string['ucp_login_start_desc'] = 'Il tuo account verrà cambiato per utilizzare {$a} per accedere a Moodle. Dopo che è stato abilitato, l\'accesso verrà eseguito utilizzando le tue credenziali {$a} - il nome utente e la password Moodle correnti non funzioneranno. In qualsiasi momento puoi disconnetterti dal tuo account e tornare a eseguire il login normalmente.';
+$string['ucp_login_stop'] = 'Non utilizzare più {$a} per accedere a Moodle';
+$string['ucp_login_stop_desc'] = 'Stai attualmente utilizzando {$a} per accedere a Moodle. Facendo clic su "Non utilizzare più il login {$a}", l\'account Moodle verrà disconnesso da {$a}. Non potrai più accedere a Moodle con il tuo account {$a}. Ti verrà chiesto di creare un nome utente e una password con cui potrai accedere a Moodle direttamente.';
+$string['ucp_login_status'] = 'Login {$a} è:';
+$string['ucp_status_enabled'] = 'Abilitato';
+$string['ucp_status_disabled'] = 'Disabilitato';
+$string['ucp_disconnect_title'] = 'Disconnessione {$a}';
+$string['ucp_disconnect_details'] = 'Il tuo account Moodle verrà disconnesso da {$a}. Per accedere a Moodle dovrai creare un nome utente e una password.';
+$string['ucp_title'] = 'Gestione {$a}';
+
+// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment
\ No newline at end of file
diff --git a/auth/oidc/lang/ja/auth_oidc.php b/auth/oidc/lang/ja/auth_oidc.php
new file mode 100644
index 00000000000..12adba7491e
--- /dev/null
+++ b/auth/oidc/lang/ja/auth_oidc.php
@@ -0,0 +1,133 @@
+.
+
+/**
+ * Japanese language strings.
+ *
+ * @package auth_oidc
+ * @author James McQuillan
+ * @author Lai Wei
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment
+
+$string['pluginname'] = 'OpenID Connect';
+$string['auth_oidcdescription'] = 'OpenID Connectプラグインは、設定可能なアイデンティティプロバイダを使用してシングルサインオン機能を提供します。';
+$string['cfg_authendpoint_key'] = '認証エンドポイント';
+$string['cfg_authendpoint_desc'] = 'アイデンティティプロバイダが使用する認証エンドポイントのURIです。';
+$string['cfg_autoappend_key'] = '自動付加';
+$string['cfg_autoappend_desc'] = 'ユーザがユーザ名/パスワードのログインフローを使用してログインした場合、自動的にこの文字列を付加します。これは、アイデンティティプロバイダが共通のドメインを求めているのものの、ユーザにログイン時に入力してほしくない場合に便利です。たとえば、完全なOpenID Connectユーザが"james@example.com"である場合、ここに"@example.com"と入力しておくと、ユーザはユーザ名として"james"を入力するだけで済みます。
注 : ユーザ名が競合する場合、つまり同じ名前のMoodleユーザが存在する場合、認証プラグインの優先順位を使用してユーザが決定されます。';
+$string['cfg_clientid_key'] = 'クライアントID';
+$string['cfg_clientid_desc'] = 'アイデンティティプロバイダに登録したクライアントID。';
+$string['cfg_clientsecret_key'] = 'クライアント秘密鍵';
+$string['cfg_clientsecret_desc'] = 'アイデンティティプロバイダに登録したクライアント秘密鍵です。プロバイダによっては、キーと呼ばれることもあります。';
+$string['cfg_err_invalidauthendpoint'] = '無効な認証エンドポイント';
+$string['cfg_err_invalidtokenendpoint'] = '無効なトークンエンドポイント';
+$string['cfg_err_invalidclientid'] = '無効なクライアントID';
+$string['cfg_err_invalidclientsecret'] = '無効なクライアント秘密鍵';
+$string['cfg_icon_key'] = 'アイコン';
+$string['cfg_icon_desc'] = 'ログインページでプロバイダ名の横に表示されるアイコンです。';
+$string['cfg_iconalt_o365'] = 'Microsoft 365アイコン';
+$string['cfg_iconalt_locked'] = 'ロック済みアイコン';
+$string['cfg_iconalt_lock'] = 'ロックアイコン';
+$string['cfg_iconalt_go'] = '緑の丸';
+$string['cfg_iconalt_stop'] = '赤の丸';
+$string['cfg_iconalt_user'] = 'ユーザアイコン';
+$string['cfg_iconalt_user2'] = '別のユーザアイコン';
+$string['cfg_iconalt_key'] = 'キーアイコン';
+$string['cfg_iconalt_group'] = 'グループアイコン';
+$string['cfg_iconalt_group2'] = '別のグループアイコン';
+$string['cfg_iconalt_mnet'] = 'MNETアイコン';
+$string['cfg_iconalt_userlock'] = 'ロック付きユーザアイコン';
+$string['cfg_iconalt_plus'] = 'プラスアイコン';
+$string['cfg_iconalt_check'] = 'チェックマークアイコン';
+$string['cfg_iconalt_rightarrow'] = '右向き矢印アイコン';
+$string['cfg_customicon_key'] = 'カスタムアイコン';
+$string['cfg_customicon_desc'] = '独自のアイコンを使用する場合は、ここにアップロードします。これにより、上記で選択していたアイコンは上書きされます。
カスタムアイコンを使用する際の注意 : - この画像はログインページではサイズ変更されません。このため、35x35ピクセル以下の画像をアップロードすることをお勧めします。
- カスタムアイコンをアップロードした後で標準のアイコンに戻す場合は、上のボックスのカスタムアイコンをクリックします。次に[削除]、[OK]をクリックし、最後にフォームの下部にある[変更の保存]をクリックします。これにより、選択された標準アイコンがMoodleログインページに表示されます。
';
+$string['cfg_debugmode_key'] = 'デバッグメッセージを記録する';
+$string['cfg_debugmode_desc'] = '有効にすると、Moodleログに情報が記録されます。これは問題を特定するのに役立つことがあります。';
+$string['cfg_loginflow_key'] = 'ログインフロー';
+$string['cfg_loginflow_authcode'] = '認証リクエスト';
+$string['cfg_loginflow_authcode_desc'] = 'このフローでは、ユーザはMoodleログインページでアイデンティティプロバイダの名前 (上記の「プロバイダ名」を参照) をクリックします。ユーザはプロバイダにリダイレクトされ、そこでログインします。ログインが成功したら、ユーザはMoodleにリダイレクトされ、透過的にMoodleログインが行われます。これは最も標準化され、最もセキュアなユーザのログイン方法です。';
+$string['cfg_loginflow_rocreds'] = 'ユーザ名/パスワード認証';
+$string['cfg_loginflow_rocreds_desc'] = 'このフローでは、手動によるログインと同様、ユーザはMoodleのログインフォームにユーザ名とパスワードを入力します。これらの認証情報はバックグラウンドでアイデンティティプロバイダに渡され、認証を取得します。ユーザはアイデンティティプロバイダと直接やり取りしないので、このフローはユーザに最も透過的です。すべてのアイデンティティプロバイダがこのフローをサポートしているわけではない点にご注意ください。';
+$string['cfg_oidcresource_key'] = 'リソース';
+$string['cfg_oidcresource_desc'] = 'リクエストを送る、OpenID Connectのリソース。';
+$string['cfg_oidcscope_key'] = '範囲';
+$string['cfg_oidcscope_desc'] = '使用するOIDCスコープ。';
+$string['cfg_opname_key'] = 'プロバイダ名';
+$string['cfg_opname_desc'] = 'これはユーザがログインするために使用する必要がある認証情報の種類を識別するラベルで、エンドユーザに表示されます。このラベルはプロバイダを識別するために、このプラグインのユーザに表示されるすべての部分で使用されます。';
+$string['cfg_redirecturi_key'] = 'リダイレクトURI';
+$string['cfg_redirecturi_desc'] = 'これは"リダイレクトURI"として登録するURIです。OpenID Connectアイデンティティプロバイダは、クライアントとしてMoodleを登録するときにこれを要求します。
注意: これは、ここに表示されているとおり「正確」にOpenID Connectプロバイダに入力する必要があります。違いがあると、OpenID Connectを使用してログインできません。';
+$string['cfg_tokenendpoint_key'] = 'トークエンドポイント';
+$string['cfg_tokenendpoint_desc'] = 'アイデンティティプロバイダが使用する、トークンエンドポイントのURIです。';
+$string['event_debug'] = 'デバッグメッセージ';
+$string['errorauthdisconnectemptypassword'] = 'パスワードは空白にできません。';
+$string['errorauthdisconnectemptyusername'] = 'ユーザ名は空白にできません。';
+$string['errorauthdisconnectusernameexists'] = 'このユーザ名は既に使用されています。別のユーザ名を選択してください。';
+$string['errorauthdisconnectnewmethod'] = 'ログイン方法を使用する';
+$string['errorauthdisconnectinvalidmethod'] = '無効なログイン方法を受信しました。';
+$string['errorauthdisconnectifmanual'] = '手動によるログインを利用する場合は、以下に認証情報を入力します。';
+$string['errorauthinvalididtoken'] = 'Invalid id_tokenを受信しました。';
+$string['errorauthloginfailednouser'] = '無効なログイン : Moodleでユーザが見つかりませんでした';
+$string['errorauthnoauthcode'] = '認証コードを受信していません。';
+$string['errorauthnocreds'] = 'OpenID Connectクライアント認証情報を設定してください。';
+$string['errorauthnoendpoints'] = 'OpenID Connectサーバエンドポイントを設定してください。';
+$string['errorauthnohttpclient'] = 'HTTPクライアントを設定してください。';
+$string['errorauthnoidtoken'] = 'OpenID接続のid_tokenを受信していません。';
+$string['errorauthunknownstate'] = '不明な状態です。';
+$string['errorauthuseralreadyconnected'] = '既に別のOpenID Connectユーザに接続しています。';
+$string['errorauthuserconnectedtodifferent'] = '認証したOpenID Connectユーザは既にMoodleユーザに接続されています。';
+$string['errorbadloginflow'] = '無効なログインフローが指定されました。注 : インストールまたはアップグレードを最近行った場合は、Moodleキャッシュをクリアしてください。';
+$string['errorjwtbadpayload'] = 'JWTペイロードを読み取れませんでした。';
+$string['errorjwtcouldnotreadheader'] = 'JWTヘッダーを読み取れませんでした';
+$string['errorjwtempty'] = '空のJWT、または文字列以外のJWTを受信しました。';
+$string['errorjwtinvalidheader'] = '無効なJWTヘッダー';
+$string['errorjwtmalformed'] = '無効な形式のJWTを受信しました。';
+$string['errorjwtunsupportedalg'] = 'JWS AlgまたはJWEがサポートされていません';
+$string['erroroidcnotenabled'] = 'OpenID Connect認証プラグインが有効になっていません。';
+$string['errornodisconnectionauthmethod'] = 'フォールバックする有効な認証プラグインがないため、接続解除できません (ユーザの以前のログイン方法または手動ログイン方法)。';
+$string['erroroidcclientinvalidendpoint'] = '無効なエンドポイントURIを受信しました。';
+$string['erroroidcclientnocreds'] = 'クライアントの認証情報と秘密鍵を設定してください';
+$string['erroroidcclientnoauthendpoint'] = '認証エンドポイントが設定されていません。$this->setendpointsを使用して設定してください。';
+$string['erroroidcclientnotokenendpoint'] = 'トークンエンドポイントが設定されていません。$this->setendpointsを使用して設定してください。';
+$string['erroroidcclientinsecuretokenendpoint'] = 'トークンエンドポイントはこのためにSSL/TLSを使用している必要があります。';
+$string['errorucpinvalidaction'] = '無効なアクションを受信しました。';
+$string['erroroidccall'] = 'OpenID接続のエラーが発生しました。詳細については、ログを確認してください。';
+$string['erroroidccall_message'] = 'OpenID接続のエラー : {$a}';
+$string['eventuserauthed'] = 'ユーザをOpenID Coonectで認証しました';
+$string['eventusercreated'] = 'ユーザをOpenID Connectで作成しました';
+$string['eventuserconnected'] = 'ユーザをOpenID Connectに接続しました';
+$string['eventuserloggedin'] = 'ユーザはOpenID Connectにログインしました';
+$string['eventuserdisconnected'] = 'ユーザはOpenID Connectから接続解除されました';
+$string['oidc:manageconnection'] = 'OpenID Connect接続を管理する';
+$string['ucp_general_intro'] = 'ここでは、{$a} への接続を管理できます。有効にした場合、個別のユーザ名とパスワードを使用する代わりに、{$a} アカウントを使用してMoodleにログインできます。接続後は、Moodleのユーザ名とパスワードを覚えておく必要がなくなります。すべてのログインは {$a} が処理します。';
+$string['ucp_login_start'] = '{$a} を使用してMoodleへのログインを開始する';
+$string['ucp_login_start_desc'] = 'アカウントが {$a} を使用してMoodleにログインするよう切り替わります。有効にした場合、{$a} の認証情報を使用してログインするようになります。現在のMoodleユーザ名とパスワードは機能しなくなります。いつでもアカウントの接続を解除し、通常のログイン方法に戻ることができます。';
+$string['ucp_login_stop'] = '{$a} を使用したMoodleへのログインを停止する';
+$string['ucp_login_stop_desc'] = '現在 {$a} を使用してMoodleにログインしています。[{$a} ログインの停止]をクリックすると、 Moodleアカウントが {$a} から接続解除されます。{$a} アカウントを使用してMoodleにログインできなくなります。 ユーザ名とパスワードを作成するように求められます。その後は、Moodleに直接ログインできるようになります。';
+$string['ucp_login_status'] = '{$a} ログインは :';
+$string['ucp_status_enabled'] = '有効';
+$string['ucp_status_disabled'] = '無効';
+$string['ucp_disconnect_title'] = '{$a} 接続解除';
+$string['ucp_disconnect_details'] = 'Moodleアカウントを {$a} から接続解除します。Moodleにログインするには、ユーザ名とパスワードを作成する必要があります。';
+$string['ucp_title'] = '{$a} 管理';
+
+// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment
\ No newline at end of file
diff --git a/auth/oidc/lang/nl/auth_oidc.php b/auth/oidc/lang/nl/auth_oidc.php
new file mode 100644
index 00000000000..c79ec358556
--- /dev/null
+++ b/auth/oidc/lang/nl/auth_oidc.php
@@ -0,0 +1,133 @@
+.
+
+/**
+ * Dutch language strings.
+ *
+ * @package auth_oidc
+ * @author James McQuillan
+ * @author Lai Wei
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment
+
+$string['pluginname'] = 'OpenID Connect';
+$string['auth_oidcdescription'] = 'De OpenID Connect-plugin verschaft de mogelijkheid voor eenmalige aanmelding met configureerbare identiteitsproviders.';
+$string['cfg_authendpoint_key'] = 'Autorisatie-eindpunt';
+$string['cfg_authendpoint_desc'] = 'De URI van het token-eindpunt van je identiteitsprovider die je moet gebruiken.';
+$string['cfg_autoappend_key'] = 'Automatisch toevoegen';
+$string['cfg_autoappend_desc'] = 'Deze tekenreeks wordt automatisch toegevoegd wanneer gebruikers zich aanmelden met de aanmeldingsflow gebruikersnaam/wachtwoord. Dit is handig als je identiteitsprovider een algemeen domein vereist en je niet wilt dat gebruikers dit bij hun aanmelding moeten invoeren. Als de volledige OpenID Connect-gebruiker bijvoorbeeld \'jan@voorbeeld.com\' is en je hier @voorbeeld.com\' invoert, hoeft de gebruiker alleen \'jan\' als gebruikersnaam in te voeren.
Opmerking: als dezelfde gebruikersnamen bestaan, dus als er een Moodle-gebruiker met dezelfde naam bestaat, wordt de prioriteit van de authenticatie-plugin gebruikt om te bepalen welke gebruiker het wordt.';
+$string['cfg_clientid_key'] = 'Client-ID';
+$string['cfg_clientid_desc'] = 'Je client-ID die bij de identiteitsprovider is geregistreerd.';
+$string['cfg_clientsecret_key'] = 'Clientgeheim';
+$string['cfg_clientsecret_desc'] = 'Je clientgeheim dat bij de identiteitsprovider is geregistreerd. Bij sommige providers wordt dit een sleutel genoemd.';
+$string['cfg_err_invalidauthendpoint'] = 'Ongeldig autorisatie-eindpunt';
+$string['cfg_err_invalidtokenendpoint'] = 'Ongeldig token-eindpunt';
+$string['cfg_err_invalidclientid'] = 'Ongeldige client-ID';
+$string['cfg_err_invalidclientsecret'] = 'Ongeldig clientgeheim';
+$string['cfg_icon_key'] = 'Pictogram';
+$string['cfg_icon_desc'] = 'Een pictogram dat naast de naam van de provider op de aanmeldingspagina wordt weergegeven.';
+$string['cfg_iconalt_o365'] = 'Microsoft 365-pictogram';
+$string['cfg_iconalt_locked'] = 'Vergrendeld-pictogram';
+$string['cfg_iconalt_lock'] = 'Vergrendelingspictogram';
+$string['cfg_iconalt_go'] = 'Groene cirkel';
+$string['cfg_iconalt_stop'] = 'Rode cirkel';
+$string['cfg_iconalt_user'] = 'Gebruikerspictogram';
+$string['cfg_iconalt_user2'] = 'Gebruikerspictogram, alternatief';
+$string['cfg_iconalt_key'] = 'Sleutelpictogram';
+$string['cfg_iconalt_group'] = 'Groepspictogram';
+$string['cfg_iconalt_group2'] = 'Groepspictogram, alternatief';
+$string['cfg_iconalt_mnet'] = 'MNET-pictogram';
+$string['cfg_iconalt_userlock'] = 'Gebruiker met vergrendelingspictogram';
+$string['cfg_iconalt_plus'] = 'Plusteken';
+$string['cfg_iconalt_check'] = 'Vinkje';
+$string['cfg_iconalt_rightarrow'] = 'Pictogram pijl-rechts';
+$string['cfg_customicon_key'] = 'Aangepast pictogram';
+$string['cfg_customicon_desc'] = 'Als je een eigen pictogram wilt gebruiken, kun je dat hier uploaden. Je overschrijft daarmee een hierboven gekozen pictogram.
Opmerkingen bij het gebruik van aangepaste pictogrammen:- Het formaat van deze afbeelding wordt niet op de aanmeldingspagina aangepast. We raden je dan ook aan een afbeelding van maximaal 35 x 35 pixels te uploaden.
- Als je een aangepast pictogram hebt geüpload en toch liever een van de standaardpictogrammen wilt gebruiken, klik dan in het vak hierboven op het aangepaste pictogram en klik op Verwijderen en op OK. Klik daarna onder in dit formulier op Wijzigingen opslaan. Het geselecteerde standaardpictogram wordt dan op de aanmeldingspagina van Moodle weergegeven.
';
+$string['cfg_debugmode_key'] = 'Foutopsporingsberichten registreren';
+$string['cfg_debugmode_desc'] = 'Als deze optie is ingeschakeld, worden gegevens in het Moodle-logboek geregistreerd die kunnen helpen bij het identificeren van problemen.';
+$string['cfg_loginflow_key'] = 'Aanmeldingsflow';
+$string['cfg_loginflow_authcode'] = 'Autorisatieverzoek';
+$string['cfg_loginflow_authcode_desc'] = 'In deze flow klikt de gebruiker op de Moodle-aanmeldingspagina op de naam van de identiteitsprovider (zie Naam provider hierboven), waarna de gebruiker naar de provider wordt omgeleid om zich aan te melden. Wanneer de gebruiker is aangemeld, wordt de gebruiker weer teruggeleid naar Moodle, waar de Moodle-aanmelding transparant wordt uitgevoerd. Dit is de meest gestandaardiseerde en veilige manier waarop de gebruiker zich kan aanmelden.';
+$string['cfg_loginflow_rocreds'] = 'Authenticatie met gebruikersnaam/wachtwoord';
+$string['cfg_loginflow_rocreds_desc'] = 'In deze flow voert de gebruiker zijn gebruikersnaam en wachtwoord in het aanmeldingsformulier van Moodle in, net als bij een handmatige aanmelding. De referenties van de gebruiker worden daarna op de achtergrond doorgegeven aan de identiteitsprovider om authenticatie te verkrijgen. Deze werkwijze is de meest transparante voor de gebruiker omdat er geen directe interactie is met de identiteitsprovider. Niet alle identiteitsproviders ondersteunen deze werkwijze.';
+$string['cfg_oidcresource_key'] = 'Bron';
+$string['cfg_oidcresource_desc'] = 'De OpenID Connect-bron waarvoor het verzoek moet worden verzonden.';
+$string['cfg_oidcscope_key'] = 'Reikwijdte';
+$string['cfg_oidcscope_desc'] = 'De te gebruiken OIDC-reikwijdte.';
+$string['cfg_opname_key'] = 'Naam provider';
+$string['cfg_opname_desc'] = 'Dit is een voor de gebruiker zichtbaar label dat aangeeft met welke type referenties de gebruiker zich moet aanmelden. Dit label wordt in alle voor de gebruiker zichtbare delen van deze plugin gebruikt om de provider aan te geven.';
+$string['cfg_redirecturi_key'] = 'Omleidings-URL';
+$string['cfg_redirecturi_desc'] = 'Dit is de URI voor registratie als de URI-omleiding. De identiteitsprovider van OpenID Connect vraagt hiernaar wanneer je Moodle als client registreert.
LET OP:je moet dit exact zo invullen in je OpenID Connect-provider als het hier wordt weergegeven. Als er verschil is, wordt aanmelding met Open ID Connect onmogelijk.';
+$string['cfg_tokenendpoint_key'] = 'Token-eindpunt';
+$string['cfg_tokenendpoint_desc'] = 'De URI van het token-eindpunt van je identiteitsprovider dat je moet gebruiken.';
+$string['event_debug'] = 'Foutopsporingsmelding';
+$string['errorauthdisconnectemptypassword'] = 'Wachtwoord kan niet leeg zijn';
+$string['errorauthdisconnectemptyusername'] = 'Gebruikersnaam kan niet leeg zijn';
+$string['errorauthdisconnectusernameexists'] = 'Deze gebruikersnaam wordt al gebruikt. Kies een andere.';
+$string['errorauthdisconnectnewmethod'] = 'Aanmeldingsmethode gebruiken';
+$string['errorauthdisconnectinvalidmethod'] = 'Ongeldige aanmeldingsmethode ontvangen.';
+$string['errorauthdisconnectifmanual'] = 'Voer hieronder je referenties in als je de handmatige aanmeldingsmethode gebruikt.';
+$string['errorauthinvalididtoken'] = 'Ongeldige id_token ontvangen.';
+$string['errorauthloginfailednouser'] = 'Ongeldige aanmelding: gebruiker niet gevonden in Moodle.';
+$string['errorauthnoauthcode'] = 'Authenticatiecode niet ontvangen.';
+$string['errorauthnocreds'] = 'Configureer de referenties van de OpenID Connect-client.';
+$string['errorauthnoendpoints'] = 'Configureer de eindpunten van de OpenID Connect-server.';
+$string['errorauthnohttpclient'] = 'Stel een HTTP-client in.';
+$string['errorauthnoidtoken'] = 'OpenID Connect id_token niet ontvangen.';
+$string['errorauthunknownstate'] = 'Onbekende toestand.';
+$string['errorauthuseralreadyconnected'] = 'Je bent al verbonden met een andere OpenID Connect-gebruiker.';
+$string['errorauthuserconnectedtodifferent'] = 'De geauthenticeerde OpenID Connect-gebruiker is al verbonden met een Moodle-gebruiker.';
+$string['errorbadloginflow'] = 'Ongeldige aanmeldingsflow opgegeven. Opmerking: maak je Moodle-cache leeg als je dit bericht ontvangt na een recente installatie of upgrade.';
+$string['errorjwtbadpayload'] = 'Kan JWT-payload niet lezen.';
+$string['errorjwtcouldnotreadheader'] = 'Kan JWT-header niet lezen';
+$string['errorjwtempty'] = 'JWT leeg of geen tekenreeks.';
+$string['errorjwtinvalidheader'] = 'Ongeldige JWT-header';
+$string['errorjwtmalformed'] = 'JWT met verkeerde indeling ontvangen.';
+$string['errorjwtunsupportedalg'] = 'JWS-algoritme of JWE niet ondersteund';
+$string['erroroidcnotenabled'] = 'De authenticatie-plugin van OpenID Connect is niet ingeschakeld.';
+$string['errornodisconnectionauthmethod'] = 'Kan verbinding niet verbreken omdat er geen ingeschakelde authenticatie-plugin is om op terug te vallen (vorige aanmeldingsmethode van gebruiker of handmatige aanmeldingsmethode).';
+$string['erroroidcclientinvalidendpoint'] = 'Ongeldige eindpunt-URI ontvangen.';
+$string['erroroidcclientnocreds'] = 'Stel clientreferenties in met setcreds';
+$string['erroroidcclientnoauthendpoint'] = 'Geen autorisatie-eindpunt ingesteld. Stel in met $this->setendpoints';
+$string['erroroidcclientnotokenendpoint'] = 'Geen token-eindpunt ingesteld. Stel in met $this->setendpoints';
+$string['erroroidcclientinsecuretokenendpoint'] = 'Het token-eindpunt moet hiervoor gebruikmaken van SSL/TLS.';
+$string['errorucpinvalidaction'] = 'Ongeldige actie ontvangen.';
+$string['erroroidccall'] = 'Fout in OpenID Connect. Controleer de logboeken voor meer informatie.';
+$string['erroroidccall_message'] = 'Fout in OpenID Connect: {$a}';
+$string['eventuserauthed'] = 'Gebruiker geautoriseerd met OpenID Connect';
+$string['eventusercreated'] = 'Gebruiker gemaakt met OpenID Connect';
+$string['eventuserconnected'] = 'Gebruiker verbonden met OpenID Connect';
+$string['eventuserloggedin'] = 'Gebruiker aangemeld met OpenID Connect';
+$string['eventuserdisconnected'] = 'Verbinding tussen gebruiker en OpenID Connect verbroken';
+$string['oidc:manageconnection'] = 'Verbinding met OpenID Connect beheren';
+$string['ucp_general_intro'] = 'Hier kun je de verbinding met {$a} beheren. Als deze optie is ingeschakeld, kun je je bij Moodle aanmelden met je {$a}-account in plaats van een aparte gebruikersnaam en wachtwoord. Als de verbinding is gemaakt, hoef je je gebruikersnaam en wachtwoord voor Moodle niet meer te onthouden. Alle aanmeldingen worden afgehandeld door {$a}.';
+$string['ucp_login_start'] = '{$a} gebruiken om je aan te melden bij Moodle';
+$string['ucp_login_start_desc'] = 'Hiermee stel je je account in voor het het gebruik van {$a} om je aan te melden bij Moodle. Als deze optie is ingeschakeld, meld je je aan met je {$a}-referenties. Je huidige Moodle-gebruikersnaam en -wachtwoord werken niet meer. Je kunt op elk moment de verbinding met je account verbreken en terugkeren naar de normale aanmelding.';
+$string['ucp_login_stop'] = '{$a} niet meer gebruiken om je aan te melden bij Moodle';
+$string['ucp_login_stop_desc'] = 'Op dit moment gebruik je {$a} om je aan te melden bij Moodle. Als je op {$a} niet meer gebruiken om je aan te melden klikt, wordt de verbinding tussen je Moodle-account en {$a} verbroken. Je kunt je niet meer bij Moodle aanmelden met je {$a}-account. Je wordt gevraagd een gebruikersnaam en wachtwoord op te geven, en vanaf dat moment kun je je direct aanmelden bij Moodle.';
+$string['ucp_login_status'] = '{$a}-aanmelding is:';
+$string['ucp_status_enabled'] = 'Ingeschakeld';
+$string['ucp_status_disabled'] = 'Uitgeschakeld';
+$string['ucp_disconnect_title'] = 'Verbinding met {$a} verbroken';
+$string['ucp_disconnect_details'] = 'Hiermee wordt de verbinding tussen je Moodle-account en {$a} verbroken. Je moet een gebruikersnaam en wachtwoord maken om je aan te melden bij Moodle.';
+$string['ucp_title'] = '{$a}-beheer';
+
+// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment
\ No newline at end of file
diff --git a/auth/oidc/lang/pl/auth_oidc.php b/auth/oidc/lang/pl/auth_oidc.php
new file mode 100644
index 00000000000..0280a400982
--- /dev/null
+++ b/auth/oidc/lang/pl/auth_oidc.php
@@ -0,0 +1,133 @@
+.
+
+/**
+ * Polish language strings.
+ *
+ * @package auth_oidc
+ * @author James McQuillan
+ * @author Lai Wei
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment
+
+$string['pluginname'] = 'OpenID Connect';
+$string['auth_oidcdescription'] = 'Wtyczka OpenID Connect udostępnia funkcję rejestracji jednokrotnej przy użyciu dostawców tożsamości, których można skonfigurować.';
+$string['cfg_authendpoint_key'] = 'Punkt końcowy autoryzacji';
+$string['cfg_authendpoint_desc'] = 'Identyfikator URI punktu końcowego autoryzacji od dostawcy tożsamości do wykorzystania.';
+$string['cfg_autoappend_key'] = 'Dołączaj automatycznie';
+$string['cfg_autoappend_desc'] = 'Automatycznie dołączaj ten ciąg przy logowaniu użytkowników za pomocą nazwy użytkownika/hasła. Jest to przydatne, gdy dostawca tożsamości wymaga stosowania wspólnej domeny, ale nie chce wymagać jej wpisywania przez użytkowników podczas logowania. Na przykład jeżeli pełna nazwa użytkownika wtyczki OpenID Connect to „jan@przyklad.com”, a w tym polu zostanie wprowadzony ciąg „@przyklad.com”, użytkownik będzie musiał jedynie wpisać słowo „jan” jako swoją nazwę użytkownika.
Uwaga: Jeżeli istnieją nazwy użytkowników powodujące konflikt, np. jeżeli istnieje użytkownik platformy Moodle o tej samej nazwie, do określenia, który użytkownik ma pierwszeństwo stosowane są ustawienia priorytetów wtyczki uwierzytelniania.';
+$string['cfg_clientid_key'] = 'Identyfikator klienta';
+$string['cfg_clientid_desc'] = 'Zarejestrowany identyfikator klienta w dostawcy tożsamości.';
+$string['cfg_clientsecret_key'] = 'Tajny klucz klienta';
+$string['cfg_clientsecret_desc'] = 'Zarejestrowany tajny klucz klienta w dostawcy tożsamości. W przypadku niektórych dostawców tożsamości jest on również określany jako klucz.';
+$string['cfg_err_invalidauthendpoint'] = 'Nieprawidłowy punkt końcowy autoryzacji';
+$string['cfg_err_invalidtokenendpoint'] = 'Nieprawidłowy punkt końcowy tokenu';
+$string['cfg_err_invalidclientid'] = 'Nieprawidłowy identyfikator klienta';
+$string['cfg_err_invalidclientsecret'] = 'Nieprawidłowy tajny klucz klienta';
+$string['cfg_icon_key'] = 'Ikona';
+$string['cfg_icon_desc'] = 'Ikona do wyświetlania obok nazwy dostawcy na stronie logowania.';
+$string['cfg_iconalt_o365'] = 'Ikona pakietu Microsoft 365';
+$string['cfg_iconalt_locked'] = 'Ikona zablokowana';
+$string['cfg_iconalt_lock'] = 'Ikona blokady';
+$string['cfg_iconalt_go'] = 'Zielony okrąg';
+$string['cfg_iconalt_stop'] = 'Czerwony okrąg';
+$string['cfg_iconalt_user'] = 'Ikona użytkownika';
+$string['cfg_iconalt_user2'] = 'Alternatywna ikona użytkownika';
+$string['cfg_iconalt_key'] = 'Ikona klucza';
+$string['cfg_iconalt_group'] = 'Ikona grupy';
+$string['cfg_iconalt_group2'] = 'Alternatywna ikona grupy';
+$string['cfg_iconalt_mnet'] = 'Ikona MNET';
+$string['cfg_iconalt_userlock'] = 'Użytkownik z ikoną blokady';
+$string['cfg_iconalt_plus'] = 'Ikona znaku plus';
+$string['cfg_iconalt_check'] = 'Ikona znaku wyboru';
+$string['cfg_iconalt_rightarrow'] = 'Ikona strzałki w prawo';
+$string['cfg_customicon_key'] = 'Niestandardowa ikona';
+$string['cfg_customicon_desc'] = 'Jeżeli użytkownik chce użyć własnej ikony, może ją przesłać za pomocą tej opcji. Nową ikoną można zastąpić dowolną ikonę wybraną powyżej.
Uwagi dotyczące używania niestandardowych ikon:- Rozmiar tego obrazu nie zostanie zmieniony na stronie logowania, zatem zalecamy załadowanie obrazu o maksymalnym rozmiarze 35x35 pikseli.
- Jeżeli użytkownik przesłał niestandardową ikonę i chce przywrócić jedną ze standardowych ikon programu, należy kliknąć ikonę niestandardową w polu powyżej i kliknąć przycisk „Usuń”. Następnie należy kliknąć przycisk „OK” oraz przycisk „Zapisz zmiany” w dolnej części formularza. Wybrana ikona standardowa będzie wyświetlana na stronie logowania do platformy Moodle.
';
+$string['cfg_debugmode_key'] = 'Rejestruj komunikaty debugowania';
+$string['cfg_debugmode_desc'] = 'Jeśli ta opcja jest włączona, informacje będą rejestrowane w pliku dziennika platformy Moodle, aby pomóc w identyfikacji problemów.';
+$string['cfg_loginflow_key'] = 'Przepływ logowania';
+$string['cfg_loginflow_authcode'] = 'Żądanie autoryzacji';
+$string['cfg_loginflow_authcode_desc'] = 'W przypadku tego przepływu użytkownik klika nazwę dostawcy tożsamości (patrz „Nazwa dostawcy” powyżej) na stronie logowania do platformy Moodle i zostaje przekierowany do dostawcy, aby się zalogować. Po pomyślnym zalogowaniu użytkownik jest ponownie przekierowywany do strony platformy Moodle, na której odbywa się logowanie do platformy Moodle w sposób niewidoczny. Jest to najbardziej ustandaryzowany i bezpieczny sposób logowania się użytkownika.';
+$string['cfg_loginflow_rocreds'] = 'Uwierzytelnienie nazwy użytkownika/hasła';
+$string['cfg_loginflow_rocreds_desc'] = 'W przypadku tego przepływu użytkownik wprowadza nazwę użytkownika i hasło do formularza logowania się do platformy Moodle w taki sam sposób jak w przypadku logowania ręcznego. Dane logowania użytkownika są następnie przesyłane do dostawcy tożsamości w tle w celu uwierzytelnienia. Ten przepływ jest najbardziej niewidoczny dla użytkownika, ponieważ użytkownik nie wchodzi w bezpośrednią interakcję z dostawcą tożsamości. Nie wszyscy dostawcy tożsamości obsługują ten przepływ.';
+$string['cfg_oidcresource_key'] = 'Zasób';
+$string['cfg_oidcresource_desc'] = 'Zasób wtyczki OpenID Connect, do którego ma zostać wysłane żądanie.';
+$string['cfg_oidcscope_key'] = 'Scope';
+$string['cfg_oidcscope_desc'] = 'Zakres OIDC do użycia.';
+$string['cfg_opname_key'] = 'Nazwa dostawcy';
+$string['cfg_opname_desc'] = 'Jest to etykieta dla użytkownika końcowego określająca rodzaj danych logowania, których użytkownik musi użyć do logowania. Ta etykieta jest używana w obszarach wtyczki widocznych dla użytkownika w celu zidentyfikowania dostawcy.';
+$string['cfg_redirecturi_key'] = 'Adres URI przekierowania';
+$string['cfg_redirecturi_desc'] = 'Jest to identyfikator URI, który należy zarejestrować jako „Adres URI przekierowania”. Dostawca tożsamości wtyczki OpenID Connect powinien zapytać o ten identyfikator podczas rejestracji platformy Moodle jako klienta.
UWAGA: Należy go wprowadzić do dostawcy OpenID Connect *dokładnie* w takiej postaci, w jakiej występuje w tym miejscu. Dowolna różnica uniemożliwi logowanie za pomocą OpenID Connect.';
+$string['cfg_tokenendpoint_key'] = 'Punkt końcowy tokenu';
+$string['cfg_tokenendpoint_desc'] = 'Adres URI punktu końcowego tokenu od dostawcy tożsamości do wykorzystania.';
+$string['event_debug'] = 'Komunikaty debugowania';
+$string['errorauthdisconnectemptypassword'] = 'Hasło nie może być puste';
+$string['errorauthdisconnectemptyusername'] = 'Pole nazwy użytkownika nie może być puste';
+$string['errorauthdisconnectusernameexists'] = 'Ta nazwa użytkownika jest już zajęta. Wybierz inną nazwę.';
+$string['errorauthdisconnectnewmethod'] = 'Użyj sposobu logowania';
+$string['errorauthdisconnectinvalidmethod'] = 'Otrzymano nieprawidłowy sposób logowania.';
+$string['errorauthdisconnectifmanual'] = 'W przypadku korzystania z ręcznego sposobu logowania wprowadź dane logowania poniżej.';
+$string['errorauthinvalididtoken'] = 'Otrzymano nieprawidłowy token identyfikatora.';
+$string['errorauthloginfailednouser'] = 'Nieprawidłowe dane logowania: nie znaleziono użytkownika w platformie Moodle.';
+$string['errorauthnoauthcode'] = 'Nie otrzymano kodu uwierzytelniania.';
+$string['errorauthnocreds'] = 'Skonfiguruj dane logowania klienta wtyczki OpenID Connect.';
+$string['errorauthnoendpoints'] = 'Skonfiguruj punkty końcowe serwera wtyczki OpenID Connect.';
+$string['errorauthnohttpclient'] = 'Ustaw klienta HTTP.';
+$string['errorauthnoidtoken'] = 'Nie otrzymano tokenu identyfikatora OpenID Connect.';
+$string['errorauthunknownstate'] = 'Stan nieznany.';
+$string['errorauthuseralreadyconnected'] = 'Połączono już z innym użytkownikiem wtyczki OpenID Connect.';
+$string['errorauthuserconnectedtodifferent'] = 'Uwierzytelniony użytkownik wtyczki OpenID Connect jest już połączony z użytkownikiem platformy Moodle.';
+$string['errorbadloginflow'] = 'Określono nieprawidłowy przepływ logowania. Uwaga: jeżeli ten komunikat jest wyświetlany po niedawnej instalacji lub aktualizacji, należy wyczyścić pamięć podręczną platformy Moodle.';
+$string['errorjwtbadpayload'] = 'Nie udało się odczytać ładunku tokenu JWT.';
+$string['errorjwtcouldnotreadheader'] = 'Nie udało się odczytać nagłówka tokenu JWT';
+$string['errorjwtempty'] = 'Otrzymano token JWT, który jest pusty lub nie jest ciągiem.';
+$string['errorjwtinvalidheader'] = 'Nieprawidłowy nagłówek tokenu JWT';
+$string['errorjwtmalformed'] = 'Otrzymano nieprawidłowo utworzony token JWT.';
+$string['errorjwtunsupportedalg'] = 'Tokeny JWS Alg lub JWE nie są obsługiwane';
+$string['erroroidcnotenabled'] = 'Wtyczka uwierzytelniania OpenID Connect nie jest włączona.';
+$string['errornodisconnectionauthmethod'] = 'Nie można odłączyć, ponieważ żadna wtyczka uwierzytelniania nie jest włączona (poprzedni sposób logowania użytkownika lub sposób logowania ręcznego).';
+$string['erroroidcclientinvalidendpoint'] = 'Otrzymano nieprawidłowy adres URI punktu końcowego.';
+$string['erroroidcclientnocreds'] = 'Ustaw dane logowania klienta przy pomocy ustawionych danych logowania';
+$string['erroroidcclientnoauthendpoint'] = 'Nie ustawiono punktu końcowego autoryzacji. Ustaw przy użyciu $this->setendpoints';
+$string['erroroidcclientnotokenendpoint'] = 'Nie ustawiono punktu końcowego tokenu. Ustaw przy użyciu $this->setendpoints';
+$string['erroroidcclientinsecuretokenendpoint'] = 'Punkt końcowy musi w tym celu korzystać z certyfikatu SSL/TLS.';
+$string['errorucpinvalidaction'] = 'Otrzymano nieprawidłowe działanie.';
+$string['erroroidccall'] = 'Błąd w OpenID Connect. Więcej informacji można znaleźć w dziennikach.';
+$string['erroroidccall_message'] = 'Błąd w OpenID Connect: {$a}';
+$string['eventuserauthed'] = 'Zautoryzowano użytkownika przy użyciu wtyczki OpenID Connect';
+$string['eventusercreated'] = 'Utworzono użytkownika we wtyczce OpenID Connect';
+$string['eventuserconnected'] = 'Podłączono użytkownika do wtyczki OpenID Connect';
+$string['eventuserloggedin'] = 'Zalogowano użytkownika za pomocą wtyczki OpenID Connect';
+$string['eventuserdisconnected'] = 'Odłączono użytkownika od wtyczki OpenID Connect';
+$string['oidc:manageconnection'] = 'Zarządzaj połączeniem z wtyczką OpenID Connect';
+$string['ucp_general_intro'] = 'Ta opcja umożliwia zarządzanie połączeniem z {$a}. Jeżeli jest włączona, użytkownik może korzystać z konta {$a} do logowania się do platformy Moodle zamiast używania oddzielnej nazwy użytkownika i hasła. Po połączeniu nie trzeba będzie pamiętać nazwy użytkownika ani hasła do platformy Moodle — wszystkie operacje logowania będą obsługiwane przez {$a}.';
+$string['ucp_login_start'] = 'Używaj {$a} w celu logowania się do platformy Moodle';
+$string['ucp_login_start_desc'] = 'Spowoduje to przełączenie konta na logowanie się do platformy Moodle przy użyciu {$a}. Po włączeniu tej opcji użytkownik będzie się logował przy użyciu danych logowania {$a} — bieżąca nazwa użytkownika i hasło do platformy Moodle nie będą działać. Można odłączyć konto w dowolnym momencie i powrócić do zwykłego sposobu logowania się.';
+$string['ucp_login_stop'] = 'Nie używaj {$a} w celu logowania się do platformy Moodle';
+$string['ucp_login_stop_desc'] = 'Obecnie używasz {$a}, aby logować się do platformy Moodle. Kliknij opcję „Nie używaj logowania {$a}”, aby odłączyć konto na platformie Moodle od {$a}. Logowanie do platformy Moodle przy użyciu konta {$a} nie będzie możliwe. Musisz utworzyć nazwę użytkownika i hasło, aby zalogować się do platformy Moodle bezpośrednio.';
+$string['ucp_login_status'] = 'Login {$a} to:';
+$string['ucp_status_enabled'] = 'Włączone';
+$string['ucp_status_disabled'] = 'Wyłączone';
+$string['ucp_disconnect_title'] = 'Rozłączono {$a}';
+$string['ucp_disconnect_details'] = 'Spowoduje to odłączenie konta na platformie Moodle od {$a}. Konieczne będzie utworzenie nazwy użytkownika i hasła w celu zalogowania się do platformy Moodle.';
+$string['ucp_title'] = 'Zarządzanie {$a}';
+
+// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment
\ No newline at end of file
diff --git a/auth/oidc/lang/pt_br/auth_oidc.php b/auth/oidc/lang/pt_br/auth_oidc.php
new file mode 100644
index 00000000000..1d2218978d8
--- /dev/null
+++ b/auth/oidc/lang/pt_br/auth_oidc.php
@@ -0,0 +1,133 @@
+.
+
+/**
+ * Portuguese - Brazil language strings.
+ *
+ * @package auth_oidc
+ * @author James McQuillan
+ * @author Lai Wei
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+// phpcs:disable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:disable moodle.Files.LangFilesOrdering.UnexpectedComment
+
+$string['pluginname'] = 'OpenID Connect';
+$string['auth_oidcdescription'] = 'O plugin OpenID Connect oferece o recurso de logon único usando provedores de identidade que podem ser configurados.';
+$string['cfg_authendpoint_key'] = 'Ponto de extremidade de autorização';
+$string['cfg_authendpoint_desc'] = 'O URI do ponto de extremidade de autorização do seu provedor de identidade a ser usado.';
+$string['cfg_autoappend_key'] = 'Acrescentar automaticamente';
+$string['cfg_autoappend_desc'] = 'Acrescente essa cadeia de caracteres automaticamente ao efetuar o login de usuários utilizando o fluxo de login com nome de usuário e senha. Isso é útil quando seu provedor de identidade exige um domínio comum, mas não quer exigir que os usuários o digitem ao fazer login. Por exemplo, se o usuário completo do OpenID Connect for "joao@exemplo.com" e você inserir "@exemplo.com" aqui, o usuário só precisará inserir "joao" como nome de usuário.
Observação: caso exista conflito entre nomes de usuários, ou seja, exista um usuário do Moodle com o mesmo nome, a prioridade do plugin de autenticação é usada para determinar qual usuário prevalecerá.';
+$string['cfg_clientid_key'] = 'ID do cliente';
+$string['cfg_clientid_desc'] = 'Seu ID do cliente registrado no provedor de identidade.';
+$string['cfg_clientsecret_key'] = 'Segredo do cliente';
+$string['cfg_clientsecret_desc'] = 'Seu segredo do cliente registrado no provedor de identidade. Em alguns provedores, ele também é chamado de chave.';
+$string['cfg_err_invalidauthendpoint'] = 'Ponto de extremidade de autorização inválido';
+$string['cfg_err_invalidtokenendpoint'] = 'Ponto de extremidade de token inválido';
+$string['cfg_err_invalidclientid'] = 'ID do cliente inválido';
+$string['cfg_err_invalidclientsecret'] = 'Segredo do cliente inválido';
+$string['cfg_icon_key'] = 'Ícone';
+$string['cfg_icon_desc'] = 'Um ícone a ser exibido ao lado do nome do provedor na página de login.';
+$string['cfg_iconalt_o365'] = 'Ícone do Microsoft 365';
+$string['cfg_iconalt_locked'] = 'Ícone de bloqueado';
+$string['cfg_iconalt_lock'] = 'Ícone de bloqueio';
+$string['cfg_iconalt_go'] = 'Círculo verde';
+$string['cfg_iconalt_stop'] = 'Círculo vermelho';
+$string['cfg_iconalt_user'] = 'Ícone do usuário';
+$string['cfg_iconalt_user2'] = 'Ícone alternativo do usuário';
+$string['cfg_iconalt_key'] = 'Ícone de chave';
+$string['cfg_iconalt_group'] = 'Ícone do grupo';
+$string['cfg_iconalt_group2'] = 'Ícone alternativo do grupo';
+$string['cfg_iconalt_mnet'] = 'Ícone da MNET';
+$string['cfg_iconalt_userlock'] = 'Ícone de usuário com bloqueio';
+$string['cfg_iconalt_plus'] = 'Ícone de sinal de adição';
+$string['cfg_iconalt_check'] = 'Ícone de marca de seleção';
+$string['cfg_iconalt_rightarrow'] = 'Ícone de seta para a direita';
+$string['cfg_customicon_key'] = 'Ícone personalizado';
+$string['cfg_customicon_desc'] = 'Se você quiser usar seu próprio ícone, faça o upload dele aqui. Isso substituirá qualquer ícone escolhido acima.
Observações sobre o uso de ícones personalizados:- Essa imagem não será redimensionada na página de login; portanto, recomendamos o upload de uma imagem de, no máximo, 35x35 pixels.
- Caso você tenha feito o upload de um ícone personalizado e queira voltar a usar um dos ícones padrão, clique no ícone personalizado na caixa acima, em "Excluir", em "OK" e depois clique em "Salvar alterações" na parte inferior deste formulário. Agora o ícone padrão selecionado será exibido na página de login do Moodle.
';
+$string['cfg_debugmode_key'] = 'Registrar mensagens de depuração';
+$string['cfg_debugmode_desc'] = 'Se essa configuração estiver ativada, informações que podem ajudar a identificar problemas serão registradas no log do Moodle.';
+$string['cfg_loginflow_key'] = 'Fluxo de login';
+$string['cfg_loginflow_authcode'] = 'Solicitação de autorização';
+$string['cfg_loginflow_authcode_desc'] = 'Ao usar esse fluxo, o usuário clicará no nome do provedor de identidade (consulte "Nome do provedor" acima) na página de login do Moodle e será redirecionado para o provedor para fazer login. Depois de efetuar com sucesso o login, o usuário será redirecionado de volta para o Moodle, onde o login ocorrerá de modo transparente. Essa é a maneira mais padronizada e segura de realizar o login do usuário.';
+$string['cfg_loginflow_rocreds'] = 'Autenticação de nome de usuário e senha';
+$string['cfg_loginflow_rocreds_desc'] = 'Ao usar esse fluxo, o usuário informará seu nome de usuário e sua senha no formulário de login do Moodle da mesma forma que faria em um login manual. As credenciais serão, então, transmitidas em segundo plano para o provedor de identidade no intuito de obter a autenticação. Esse fluxo é o mais simples para o usuário, pois ele não interage diretamente com o provedor de identidade. Tenha em mente que nem todos os provedores de identidade aceitam a utilização desse fluxo.';
+$string['cfg_oidcresource_key'] = 'Recurso';
+$string['cfg_oidcresource_desc'] = 'O recurso do OpenID Connect para o qual a solicitação deverá ser enviada.';
+$string['cfg_oidcscope_key'] = 'Escopo';
+$string['cfg_oidcscope_desc'] = 'O escopo do OIDC a ser usado.';
+$string['cfg_opname_key'] = 'Nome do provedor';
+$string['cfg_opname_desc'] = 'Esse é um rótulo visível para o usuário que identifica o tipo de credenciais que devem ser utilizadas pelo usuário no login. Esse rótulo é usado em todas as partes visíveis para o usuário deste plugin para a identificação do seu provedor.';
+$string['cfg_redirecturi_key'] = 'URI de redirecionamento';
+$string['cfg_redirecturi_desc'] = 'Esse é o URI a ser registrado como o "URI de redirecionamento". Seu provedor de identidade do OpenID Connect deve solicitá-lo ao registrar o Moodle como cliente.
OBSERVAÇÃO: é necessário inserir essa informação no seu provedor do OpenID Connect EXATAMENTE como ela é exibida aqui. Qualquer diferença impedirá que logins sejam efetuados usando o OpenID Connect.';
+$string['cfg_tokenendpoint_key'] = 'Ponto de extremidade de token';
+$string['cfg_tokenendpoint_desc'] = 'O URI do ponto de extremidade de token do seu provedor de identidade a ser usado.';
+$string['event_debug'] = 'Mensagem de depuração';
+$string['errorauthdisconnectemptypassword'] = 'A senha não pode ficar em branco';
+$string['errorauthdisconnectemptyusername'] = 'O nome de usuário não pode ficar em branco';
+$string['errorauthdisconnectusernameexists'] = 'Esse nome de usuário já está em uso. Escolha outro nome.';
+$string['errorauthdisconnectnewmethod'] = 'Usar método de login';
+$string['errorauthdisconnectinvalidmethod'] = 'Método de login inválido recebido.';
+$string['errorauthdisconnectifmanual'] = 'Se estiver usando o método de login manual, insira as credenciais abaixo.';
+$string['errorauthinvalididtoken'] = 'id_token inválido recebido.';
+$string['errorauthloginfailednouser'] = 'Login inválido: usuário não encontrado no Moodle.';
+$string['errorauthnoauthcode'] = 'Código de autorização não recebido.';
+$string['errorauthnocreds'] = 'Configure as credenciais de cliente do OpenID Connect.';
+$string['errorauthnoendpoints'] = 'Configure os pontos de extremidade de servidor do OpenID Connect.';
+$string['errorauthnohttpclient'] = 'Defina um cliente de HTTP.';
+$string['errorauthnoidtoken'] = 'O id_token do OpenID Connect não foi recebido.';
+$string['errorauthunknownstate'] = 'Estado desconhecido.';
+$string['errorauthuseralreadyconnected'] = 'Você já está conectado a um usuário diferente do OpenID Connect.';
+$string['errorauthuserconnectedtodifferent'] = 'O usuário do OpenID Connect que realizou a autenticação já está conectado a um usuário do Moodle.';
+$string['errorbadloginflow'] = 'Fluxo de login inválido especificado. Observação: se você recebeu esta mensagem após uma instalação ou atualização recente, limpe seu cache do Moodle.';
+$string['errorjwtbadpayload'] = 'Não foi possível ler o conteúdo de JWT.';
+$string['errorjwtcouldnotreadheader'] = 'Não foi possível ler o cabeçalho de JWT.';
+$string['errorjwtempty'] = 'Cadeia de caracteres vazia ou inválida de JWT recebida.';
+$string['errorjwtinvalidheader'] = 'Cabeçalho de JWT inválido';
+$string['errorjwtmalformed'] = 'JWT malformado recebido.';
+$string['errorjwtunsupportedalg'] = 'JWS Alg ou JWE não compatível';
+$string['erroroidcnotenabled'] = 'O plugin de autenticação do OpenID Connect não está ativado.';
+$string['errornodisconnectionauthmethod'] = 'Não é possível se desconectar, pois não há plugin de autenticação ativado ao qual retornar (o método de login anterior do usuário ou o método de login manual).';
+$string['erroroidcclientinvalidendpoint'] = 'URI de ponto de extremidade inválido recebido.';
+$string['erroroidcclientnocreds'] = 'Defina as credenciais de cliente com setcreds';
+$string['erroroidcclientnoauthendpoint'] = 'Nenhum ponto de extremidade de autorização definido. Defina-o com $this->setendpoints';
+$string['erroroidcclientnotokenendpoint'] = 'Nenhum ponto de extremidade de token definido. Defina-o com $this->setendpoints';
+$string['erroroidcclientinsecuretokenendpoint'] = 'Para isso, é necessário que o ponto de extremidade de token esteja usando SSL/TLS.';
+$string['errorucpinvalidaction'] = 'Ação inválida recebida.';
+$string['erroroidccall'] = 'Erro no OpenID Connect. Verifique os logs para obter mais informações.';
+$string['erroroidccall_message'] = 'Erro no OpenID Connect: {$a}';
+$string['eventuserauthed'] = 'Usuário autorizado com o OpenID Connect';
+$string['eventusercreated'] = 'Usuário criado com o OpenID Connect';
+$string['eventuserconnected'] = 'Usuário conectado ao OpenID Connect';
+$string['eventuserloggedin'] = 'Usuário com login efetuado no OpenID Connect';
+$string['eventuserdisconnected'] = 'Usuário desconectado do OpenID Connect';
+$string['oidc:manageconnection'] = 'Gerenciar conexão ao OpenID Connect';
+$string['ucp_general_intro'] = 'Aqui você pode gerenciar sua conexão ao {$a}. Se essa configuração estiver ativada, você poderá usar sua conta do {$a} para fazer login no Moodle em vez de precisar de nome de usuário e senha separados. Depois que estiver conectado, você não precisará mais se lembrar de um nome de usuário e uma senha para o Moodle, pois todos os logins serão administrados pelo {$a}.';
+$string['ucp_login_start'] = 'Começar a usar o {$a} para fazer login no Moodle';
+$string['ucp_login_start_desc'] = 'Essa configuração fará uma alteração na sua conta, que passará a usar o {$a} para fazer login no Moodle. Depois de ativada, você fará login usando suas credenciais do {$a}; seu nome de usuário e sua senha do Moodle não serão aceitos. Você pode desconectar sua conta quando quiser e voltar a fazer login como antes.';
+$string['ucp_login_stop'] = 'Parar de usar o {$a} para fazer login no Moodle';
+$string['ucp_login_stop_desc'] = 'No momento, você está usando o {$a} para fazer login no Moodle. Ao clicar em "Para de usar o login do {$a}", você desconectará sua conta do Moodle do {$a}. Você não poderá mais fazer login no Moodle com sua conta do {$a} e precisará criar um nome de usuário e uma senha para poder fazer login diretamente no Moodle.';
+$string['ucp_login_status'] = 'O login via {$a} está:';
+$string['ucp_status_enabled'] = 'Ativado';
+$string['ucp_status_disabled'] = 'Desativado';
+$string['ucp_disconnect_title'] = 'Desconexão do {$a}';
+$string['ucp_disconnect_details'] = 'Essa ação desconectará sua conta do Moodle do {$a}. Você precisará criar um nome de usuário e uma senha para fazer login no Moodle.';
+$string['ucp_title'] = 'Gerenciamento do {$a}';
+
+// phpcs:enable moodle.Files.LangFilesOrdering.IncorrectOrder
+// phpcs:enable moodle.Files.LangFilesOrdering.UnexpectedComment
\ No newline at end of file
diff --git a/auth/oidc/lib.php b/auth/oidc/lib.php
new file mode 100644
index 00000000000..482060daafb
--- /dev/null
+++ b/auth/oidc/lib.php
@@ -0,0 +1,772 @@
+.
+
+/**
+ * Plugin library.
+ *
+ * @package auth_oidc
+ * @author James McQuillan
+ * @author Lai Wei
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+use auth_oidc\jwt;
+use auth_oidc\utils;
+
+// IdP types.
+/**
+ * Microsoft Entra ID identity provider type.
+ */
+const AUTH_OIDC_IDP_TYPE_MICROSOFT_ENTRA_ID = 1;
+
+/**
+ * Microsoft Identity Platform identity provider type.
+ */
+const AUTH_OIDC_IDP_TYPE_MICROSOFT_IDENTITY_PLATFORM = 2;
+
+/**
+ * Other identity provider type.
+ */
+const AUTH_OIDC_IDP_TYPE_OTHER = 3;
+
+// Microsoft Entra ID / Microsoft endpoint version.
+/**
+ * Unknown Microsoft endpoint version.
+ */
+const AUTH_OIDC_MICROSOFT_ENDPOINT_VERSION_UNKNOWN = 0;
+
+/**
+ * Microsoft endpoint version 1.
+ */
+const AUTH_OIDC_MICROSOFT_ENDPOINT_VERSION_1 = 1;
+
+/**
+ * Microsoft endpoint version 2.
+ */
+const AUTH_OIDC_MICROSOFT_ENDPOINT_VERSION_2 = 2;
+
+// OIDC application authentication method.
+/**
+ * OIDC application authentication method using secret.
+ */
+const AUTH_OIDC_AUTH_METHOD_SECRET = 1;
+
+/**
+ * OIDC application authentication method using certificate.
+ */
+const AUTH_OIDC_AUTH_METHOD_CERTIFICATE = 2;
+
+// OIDC application auth certificate source.
+/**
+ * OIDC application authentication certificate source from text.
+ */
+const AUTH_OIDC_AUTH_CERT_SOURCE_TEXT = 1;
+
+/**
+ * OIDC application authentication certificate source from file.
+ */
+const AUTH_OIDC_AUTH_CERT_SOURCE_FILE = 2;
+
+/**
+ * Initialize custom icon for OIDC authentication.
+ *
+ * This function sets up a custom icon for the OIDC plugin by creating necessary directories
+ * and copying the file into the specified location in Moodle's data directory.
+ *
+ * @param string $filefullname Full name of the custom icon file.
+ * @return bool False if the file is missing or is a directory; void otherwise.
+ */
+function auth_oidc_initialize_customicon($filefullname) {
+ global $CFG;
+
+ $file = get_config('auth_oidc', 'customicon');
+ $systemcontext = \context_system::instance();
+ $fullpath = "/{$systemcontext->id}/auth_oidc/customicon/0{$file}";
+
+ $fs = get_file_storage();
+ if (!($file = $fs->get_file_by_hash(sha1($fullpath))) || $file->is_directory()) {
+ return false;
+ }
+ $pixpluginsdir = 'pix_plugins/auth/oidc/0';
+ $pixpluginsdirparts = explode('/', $pixpluginsdir);
+ $curdir = $CFG->dataroot;
+ foreach ($pixpluginsdirparts as $dir) {
+ $curdir .= '/' . $dir;
+ if (!file_exists($curdir)) {
+ mkdir($curdir);
+ }
+ }
+
+ if (file_exists($CFG->dataroot . '/pix_plugins/auth/oidc/0')) {
+ $file->copy_content_to($CFG->dataroot . '/pix_plugins/auth/oidc/0/customicon.jpg');
+ theme_reset_all_caches();
+ }
+}
+
+/**
+ * Check for connection abilities.
+ *
+ * @param int $userid Moodle user id to check permissions for.
+ * @param string $mode Mode to check
+ * 'connect' to check for connect specific capability
+ * 'disconnect' to check for disconnect capability.
+ * 'both' to check for disconnect and connect capability.
+ * @param boolean $require Use require_capability rather than has_capability.
+ *
+ * @return boolean True if has capability.
+ */
+function auth_oidc_connectioncapability($userid, $mode = 'connect', $require = false) {
+ $check = 'has_capability';
+ if ($require) {
+ // If requiring the capability and user has manageconnection than checking connect and disconnect is not needed.
+ $check = 'require_capability';
+ if (has_capability('auth/oidc:manageconnection', \context_user::instance($userid), $userid)) {
+ return true;
+ }
+ } else if ($check('auth/oidc:manageconnection', \context_user::instance($userid), $userid)) {
+ return true;
+ }
+
+ $result = false;
+ switch ($mode) {
+ case "connect":
+ $result = $check('auth/oidc:manageconnectionconnect', \context_user::instance($userid), $userid);
+ break;
+ case "disconnect":
+ $result = $check('auth/oidc:manageconnectiondisconnect', \context_user::instance($userid), $userid);
+ break;
+ case "both":
+ $result = $check('auth/oidc:manageconnectionconnect', \context_user::instance($userid), $userid);
+ $result = $result && $check('auth/oidc:manageconnectiondisconnect', \context_user::instance($userid), $userid);
+ }
+ if ($require) {
+ return true;
+ }
+
+ return $result;
+}
+
+/**
+ * Determine if local_o365 plugins is installed.
+ *
+ * @return bool
+ */
+function auth_oidc_is_local_365_installed() {
+ global $CFG, $DB;
+
+ $dbmanager = $DB->get_manager();
+
+ return file_exists($CFG->dirroot . '/local/o365/version.php') &&
+ $DB->record_exists('config_plugins', ['plugin' => 'local_o365', 'name' => 'version']) &&
+ $dbmanager->table_exists('local_o365_objects') &&
+ $dbmanager->table_exists('local_o365_connections');
+}
+
+/**
+ * Return details of all auth_oidc tokens having empty Moodle user IDs.
+ *
+ * @return array
+ */
+function auth_oidc_get_tokens_with_empty_ids() {
+ global $DB;
+
+ $emptyuseridtokens = [];
+
+ $records = $DB->get_records('auth_oidc_token', ['userid' => '0']);
+
+ foreach ($records as $record) {
+ $item = new stdClass();
+ $item->id = $record->id;
+ $item->oidcusername = $record->oidcusername;
+ $item->useriditifier = $record->useridentifier;
+ $item->moodleusername = $record->username;
+ $item->userid = 0;
+ $item->oidcuniqueid = $record->oidcuniqid;
+ $item->matchingstatus = get_string('unmatched', 'auth_oidc');
+ $item->details = get_string('na', 'auth_oidc');
+ $deletetokenurl = new moodle_url('/auth/oidc/cleanupoidctokens.php', ['id' => $record->id]);
+ $item->action = html_writer::link($deletetokenurl, get_string('delete_token', 'auth_oidc'));
+
+ $emptyuseridtokens[$record->id] = $item;
+ }
+
+ return $emptyuseridtokens;
+}
+
+/**
+ * Return details of all auth_oidc tokens with matching Moodle user IDs, but mismatched usernames.
+ *
+ * @return array
+ */
+function auth_oidc_get_tokens_with_mismatched_usernames() {
+ global $DB;
+
+ $mismatchedtokens = [];
+
+ $sql = 'SELECT tok.id AS id, tok.userid AS tokenuserid, tok.username AS tokenusername, tok.oidcusername AS oidcusername,
+ tok.useridentifier, tok.oidcuniqid as oidcuniqid, u.id AS muserid, u.username AS musername
+ FROM {auth_oidc_token} tok
+ JOIN {user} u ON u.id = tok.userid
+ WHERE tok.userid != 0
+ AND u.username != tok.username';
+ $records = $DB->get_recordset_sql($sql);
+ foreach ($records as $record) {
+ $item = new stdClass();
+ $item->id = $record->id;
+ $item->oidcusername = $record->oidcusername;
+ $item->useridentifier = $record->useridentifier;
+ $item->userid = $record->muserid;
+ $item->oidcuniqueid = $record->oidcuniqid;
+ $item->matchingstatus = get_string('mismatched', 'auth_oidc');
+ $item->details = get_string('mismatched_details', 'auth_oidc',
+ ['tokenusername' => $record->tokenusername, 'moodleusername' => $record->musername]);
+ $deletetokenurl = new moodle_url('/auth/oidc/cleanupoidctokens.php', ['id' => $record->id]);
+ $item->action = html_writer::link($deletetokenurl, get_string('delete_token_and_reference', 'auth_oidc'));
+
+ $mismatchedtokens[$record->id] = $item;
+ }
+
+ return $mismatchedtokens;
+}
+
+/**
+ * Delete the auth_oidc token with the ID.
+ *
+ * @param int $tokenid
+ */
+function auth_oidc_delete_token(int $tokenid): void {
+ global $DB;
+
+ if (auth_oidc_is_local_365_installed()) {
+ $sql = 'SELECT obj.id, obj.objectid, tok.token, u.id AS userid, u.email
+ FROM {local_o365_objects} obj
+ JOIN {auth_oidc_token} tok ON obj.o365name = tok.username
+ JOIN {user} u ON obj.moodleid = u.id
+ WHERE obj.type = :type AND tok.id = :tokenid';
+ if ($objectrecord = $DB->get_record_sql($sql, ['type' => 'user', 'tokenid' => $tokenid], IGNORE_MULTIPLE)) {
+ // Delete record from local_o365_objects.
+ $DB->delete_records('local_o365_objects', ['id' => $objectrecord->id]);
+
+ // Delete record from local_o365_token.
+ $DB->delete_records('local_o365_token', ['user_id' => $objectrecord->userid]);
+
+ // Delete record from local_o365_connections.
+ $DB->delete_records_select('local_o365_connections', 'muserid = :userid OR LOWER(entraidupn) = :email',
+ ['userid' => $objectrecord->userid, 'email' => $objectrecord->email]);
+ }
+ }
+
+ $DB->delete_records('auth_oidc_token', ['id' => $tokenid]);
+}
+
+/**
+ * Return the list of remote field options in field mapping.
+ *
+ * @return array
+ */
+function auth_oidc_get_remote_fields() {
+ if (auth_oidc_is_local_365_installed()) {
+ $remotefields = [
+ '' => get_string('settings_fieldmap_feild_not_mapped', 'auth_oidc'),
+ 'bindingusernameclaim' => get_string('settings_fieldmap_field_bindingusernameclaim', 'auth_oidc'),
+ 'objectId' => get_string('settings_fieldmap_field_objectId', 'auth_oidc'),
+ 'userPrincipalName' => get_string('settings_fieldmap_field_userPrincipalName', 'auth_oidc'),
+ 'displayName' => get_string('settings_fieldmap_field_displayName', 'auth_oidc'),
+ 'givenName' => get_string('settings_fieldmap_field_givenName', 'auth_oidc'),
+ 'surname' => get_string('settings_fieldmap_field_surname', 'auth_oidc'),
+ 'mail' => get_string('settings_fieldmap_field_mail', 'auth_oidc'),
+ 'onPremisesSamAccountName' => get_string('settings_fieldmap_field_onPremisesSamAccountName', 'auth_oidc'),
+ 'streetAddress' => get_string('settings_fieldmap_field_streetAddress', 'auth_oidc'),
+ 'city' => get_string('settings_fieldmap_field_city', 'auth_oidc'),
+ 'postalCode' => get_string('settings_fieldmap_field_postalCode', 'auth_oidc'),
+ 'state' => get_string('settings_fieldmap_field_state', 'auth_oidc'),
+ 'country' => get_string('settings_fieldmap_field_country', 'auth_oidc'),
+ 'jobTitle' => get_string('settings_fieldmap_field_jobTitle', 'auth_oidc'),
+ 'department' => get_string('settings_fieldmap_field_department', 'auth_oidc'),
+ 'companyName' => get_string('settings_fieldmap_field_companyName', 'auth_oidc'),
+ 'preferredLanguage' => get_string('settings_fieldmap_field_preferredLanguage', 'auth_oidc'),
+ 'employeeId' => get_string('settings_fieldmap_field_employeeId', 'auth_oidc'),
+ 'businessPhones' => get_string('settings_fieldmap_field_businessPhones', 'auth_oidc'),
+ 'faxNumber' => get_string('settings_fieldmap_field_faxNumber', 'auth_oidc'),
+ 'mobilePhone' => get_string('settings_fieldmap_field_mobilePhone', 'auth_oidc'),
+ 'officeLocation' => get_string('settings_fieldmap_field_officeLocation', 'auth_oidc'),
+ 'preferredName' => get_string('settings_fieldmap_field_preferredName', 'auth_oidc'),
+ 'manager' => get_string('settings_fieldmap_field_manager', 'auth_oidc'),
+ 'manager_email' => get_string('settings_fieldmap_field_manager_email', 'auth_oidc'),
+ 'teams' => get_string('settings_fieldmap_field_teams', 'auth_oidc'),
+ 'groups' => get_string('settings_fieldmap_field_groups', 'auth_oidc'),
+ 'roles' => get_string('settings_fieldmap_field_roles', 'auth_oidc'),
+ ];
+
+ $order = 0;
+ while ($order++ < 15) {
+ $remotefields['extensionAttribute' . $order] = get_string('settings_fieldmap_field_extensionattribute', 'auth_oidc',
+ $order);
+ }
+
+ // SDS profile sync.
+ [$sdsprofilesyncenabled, $schoolid, $schoolname] = local_o365\feature\sds\utils::get_profile_sync_status_with_id_name();
+
+ if ($sdsprofilesyncenabled) {
+ $remotefields['sds_school_id'] = get_string('settings_fieldmap_field_sds_school_id', 'auth_oidc',
+ get_config('local_o365', 'sdsprofilesync', $schoolid));
+ $remotefields['sds_school_name'] = get_string('settings_fieldmap_field_sds_school_name', 'auth_oidc', $schoolname);
+ $remotefields['sds_school_role'] = get_string('settings_fieldmap_field_sds_school_role', 'auth_oidc');
+ $remotefields['sds_student_externalId'] = get_string('settings_fieldmap_field_sds_student_externalId', 'auth_oidc');
+ $remotefields['sds_student_birthDate'] = get_string('settings_fieldmap_field_sds_student_birthDate', 'auth_oidc');
+ $remotefields['sds_student_grade'] = get_string('settings_fieldmap_field_sds_student_grade', 'auth_oidc');
+ $remotefields['sds_student_graduationYear'] = get_string('settings_fieldmap_field_sds_student_graduationYear',
+ 'auth_oidc');
+ $remotefields['sds_student_studentNumber'] = get_string('settings_fieldmap_field_sds_student_studentNumber',
+ 'auth_oidc');
+ $remotefields['sds_teacher_externalId'] = get_string('settings_fieldmap_field_sds_teacher_externalId', 'auth_oidc');
+ $remotefields['sds_teacher_teacherNumber'] = get_string('settings_fieldmap_field_sds_teacher_teacherNumber',
+ 'auth_oidc');
+ }
+ } else {
+ $remotefields = [
+ '' => get_string('settings_fieldmap_feild_not_mapped', 'auth_oidc'),
+ 'bindingusernameclaim' => get_string('settings_fieldmap_field_bindingusernameclaim', 'auth_oidc'),
+ 'objectId' => get_string('settings_fieldmap_field_objectId', 'auth_oidc'),
+ 'userPrincipalName' => get_string('settings_fieldmap_field_userPrincipalName', 'auth_oidc'),
+ 'givenName' => get_string('settings_fieldmap_field_givenName', 'auth_oidc'),
+ 'surname' => get_string('settings_fieldmap_field_surname', 'auth_oidc'),
+ 'mail' => get_string('settings_fieldmap_field_mail', 'auth_oidc'),
+ ];
+ }
+
+ return $remotefields;
+}
+
+/**
+ * Return the list of available remote fields to map email field.
+ *
+ * @return array
+ */
+function auth_oidc_get_email_remote_fields() {
+ $remotefields = [
+ 'mail' => get_string('settings_fieldmap_field_mail', 'auth_oidc'),
+ 'userPrincipalName' => get_string('settings_fieldmap_field_userPrincipalName', 'auth_oidc'),
+ ];
+
+ return $remotefields;
+}
+
+/**
+ * Return the current field mapping settings in an array.
+ *
+ * @return array
+ */
+function auth_oidc_get_field_mappings() {
+ $fieldmappings = [];
+
+ $userfields = auth_oidc_get_all_user_fields();
+
+ $authoidcconfig = get_config('auth_oidc');
+
+ foreach ($userfields as $userfield) {
+ $fieldmapsettingname = 'field_map_' . $userfield;
+ if (property_exists($authoidcconfig, $fieldmapsettingname) && $authoidcconfig->$fieldmapsettingname) {
+ $fieldsetting = [];
+ $fieldsetting['field_map'] = $authoidcconfig->$fieldmapsettingname;
+
+ $fieldlocksettingname = 'field_lock_' . $userfield;
+ if (property_exists($authoidcconfig, $fieldlocksettingname)) {
+ $fieldsetting['field_lock'] = $authoidcconfig->$fieldlocksettingname;
+ } else {
+ $fieldsetting['field_lock'] = 'unlocked';
+ }
+
+ $fieldupdatelocksettignname = 'field_updatelocal_' . $userfield;
+ if (property_exists($authoidcconfig, $fieldupdatelocksettignname)) {
+ $fieldsetting['update_local'] = $authoidcconfig->$fieldupdatelocksettignname;
+ } else {
+ $fieldsetting['update_local'] = 'always';
+ }
+
+ $fieldmappings[$userfield] = $fieldsetting;
+ }
+ }
+
+ if (!array_key_exists('email', $fieldmappings)) {
+ $fieldmappings['email'] = auth_oidc_apply_default_email_mapping();
+ }
+
+ return $fieldmappings;
+}
+
+/**
+ * Apply default email mapping settings.
+ *
+ * @return array
+ */
+function auth_oidc_apply_default_email_mapping() {
+ $existingsetting = get_config('auth_oidc', 'field_map_email');
+ if ($existingsetting != 'mail') {
+ add_to_config_log('field_map_email', $existingsetting, 'mail', 'auth_oidc');
+ }
+ set_config('field_map_email', 'mail', 'auth_oidc');
+
+ $authoidcconfig = get_config('auth_oidc');
+
+ $fieldsetting = [];
+ $fieldsetting['field_map'] = 'mail';
+
+ if (property_exists($authoidcconfig, 'field_lock_email')) {
+ $fieldsetting['field_lock'] = $authoidcconfig->field_lock_email;
+ } else {
+ $fieldsetting['field_lock'] = 'unlocked';
+ }
+
+ if (property_exists($authoidcconfig, 'field_updatelocal_email')) {
+ $fieldsetting['update_local'] = $authoidcconfig->field_updatelocal_email;
+ } else {
+ $fieldsetting['update_local'] = 'always';
+ }
+
+ return $fieldsetting;
+}
+
+/**
+ * Helper function used to print mapping and locking for auth_oidc plugin on admin pages.
+ *
+ * @param stdclass $settings Moodle admin settings instance
+ * @param string $auth authentication plugin shortname
+ * @param array $userfields user profile fields
+ * @param string $helptext help text to be displayed at top of form
+ * @param boolean $mapremotefields Map fields or lock only.
+ * @param boolean $updateremotefields Allow remote updates
+ * @param array $customfields list of custom profile fields
+ */
+function auth_oidc_display_auth_lock_options($settings, $auth, $userfields, $helptext, $mapremotefields, $updateremotefields,
+ $customfields = []) {
+ global $DB;
+
+ // Introductory explanation and help text.
+ if ($mapremotefields) {
+ $settings->add(new admin_setting_heading($auth.'/data_mapping', new lang_string('auth_data_mapping', 'auth'), $helptext));
+ } else {
+ $settings->add(new admin_setting_heading($auth.'/auth_fieldlocks', new lang_string('auth_fieldlocks', 'auth'), $helptext));
+ }
+
+ // Generate the list of options.
+ $lockoptions = [
+ 'unlocked' => get_string('unlocked', 'auth'),
+ 'unlockedifempty' => get_string('unlockedifempty', 'auth'),
+ 'locked' => get_string('locked', 'auth'),
+ ];
+
+ if (auth_oidc_is_local_365_installed()) {
+ $alwaystext = get_string('update_oncreate_and_onlogin_and_usersync', 'auth_oidc');
+ $onlogintext = get_string('update_onlogin_and_usersync', 'auth_oidc');
+ } else {
+ $alwaystext = get_string('update_oncreate_and_onlogin', 'auth_oidc');
+ $onlogintext = get_string('update_onlogin', 'auth');
+ }
+ $updatelocaloptions = [
+ 'always' => $alwaystext,
+ 'oncreate' => get_string('update_oncreate', 'auth'),
+ 'onlogin' => $onlogintext,
+ ];
+
+ $updateextoptions = [
+ '0' => get_string('update_never', 'auth'),
+ '1' => get_string('update_onupdate', 'auth'),
+ ];
+
+ // Generate the list of profile fields to allow updates / lock.
+ if (!empty($customfields)) {
+ $userfields = array_merge($userfields, $customfields);
+ $customfieldname = $DB->get_records('user_info_field', null, '', 'shortname, name');
+ }
+
+ $remotefields = auth_oidc_get_remote_fields();
+ $emailremotefields = auth_oidc_get_email_remote_fields();
+
+ foreach ($userfields as $field) {
+ // Define the fieldname we display to the user.
+ // this includes special handling for some profile fields.
+ $fieldname = $field;
+ $fieldnametoolong = false;
+ if ($fieldname === 'lang') {
+ $fieldname = get_string('language');
+ } else if (!empty($customfields) && in_array($field, $customfields)) {
+ // If custom field then pick name from database.
+ $fieldshortname = str_replace('profile_field_', '', $fieldname);
+ $fieldname = $customfieldname[$fieldshortname]->name;
+ if (core_text::strlen($fieldshortname) > 67) {
+ // If custom profile field name is longer than 67 characters we will not be able to store the setting
+ // such as 'field_updateremote_profile_field_NOTSOSHORTSHORTNAME' in the database because the character
+ // limit for the setting name is 100.
+ $fieldnametoolong = true;
+ }
+ } else if ($fieldname == 'url') {
+ $fieldname = get_string('webpage');
+ } else {
+ $fieldname = get_string($fieldname);
+ }
+
+ // Generate the list of fields / mappings.
+ if ($fieldnametoolong) {
+ // Display a message that the field can not be mapped because it's too long.
+ $url = new moodle_url('/user/profile/index.php');
+ $a = (object)['fieldname' => s($fieldname), 'shortname' => s($field), 'charlimit' => 67, 'link' => $url->out()];
+ $settings->add(new admin_setting_heading($auth.'/field_not_mapped_'.sha1($field), '',
+ get_string('cannotmapfield', 'auth', $a)));
+ } else if ($mapremotefields) {
+ // We are mapping to a remote field here.
+ // Mapping.
+ if ($field == 'email') {
+ $settings->add(new admin_setting_configselect("auth_oidc/field_map_{$field}",
+ get_string('auth_fieldmapping', 'auth', $fieldname), '', null, $emailremotefields));
+ } else {
+ $settings->add(new admin_setting_configselect("auth_oidc/field_map_{$field}",
+ get_string('auth_fieldmapping', 'auth', $fieldname), '', null, $remotefields));
+ }
+
+ // Update local.
+ $settings->add(new admin_setting_configselect("auth_{$auth}/field_updatelocal_{$field}",
+ get_string('auth_updatelocalfield', 'auth', $fieldname), '', 'always', $updatelocaloptions));
+
+ // Update remote.
+ if ($updateremotefields) {
+ $settings->add(new admin_setting_configselect("auth_{$auth}/field_updateremote_{$field}",
+ get_string('auth_updateremotefield', 'auth', $fieldname), '', 0, $updateextoptions));
+ }
+
+ // Lock fields.
+ $settings->add(new admin_setting_configselect("auth_{$auth}/field_lock_{$field}",
+ get_string('auth_fieldlockfield', 'auth', $fieldname), '', 'unlocked', $lockoptions));
+ } else {
+ // Lock fields Only.
+ $settings->add(new admin_setting_configselect("auth_{$auth}/field_lock_{$field}",
+ get_string('auth_fieldlockfield', 'auth', $fieldname), '', 'unlocked', $lockoptions));
+ }
+ }
+}
+
+/**
+ * Return all user profile field names in an array.
+ *
+ * @return array|string[]|null
+ */
+function auth_oidc_get_all_user_fields() {
+ $authplugin = get_auth_plugin('oidc');
+ $userfields = $authplugin->userfields;
+ $userfields = array_merge($userfields, $authplugin->get_custom_user_profile_fields());
+
+ return $userfields;
+}
+
+/**
+ * Determine the endpoint version of the given Microsoft Entra ID / Microsoft authorization or token endpoint.
+ *
+ * @param string $endpoint The URL of the endpoint to be checked.
+ * @return int The version of the Microsoft endpoint (1 or 2) or unknown.
+ */
+function auth_oidc_determine_endpoint_version(string $endpoint) {
+ $endpointversion = AUTH_OIDC_MICROSOFT_ENDPOINT_VERSION_UNKNOWN;
+
+ if (strpos($endpoint, 'https://login.microsoftonline.com/') === 0) {
+ if (strpos($endpoint, 'oauth2/v2.0/') !== false) {
+ $endpointversion = AUTH_OIDC_MICROSOFT_ENDPOINT_VERSION_2;
+ } else if (strpos($endpoint, 'oauth2') !== false) {
+ $endpointversion = AUTH_OIDC_MICROSOFT_ENDPOINT_VERSION_1;
+ }
+ }
+
+ return $endpointversion;
+}
+
+/**
+ * Return formatted form element name to be used by configuration variables in custom forms.
+ *
+ * @param string $stringid
+ * @return string
+ */
+function auth_oidc_config_name_in_form(string $stringid) {
+ $formatedformitemname = get_string($stringid, 'auth_oidc') .
+ html_writer::span('auth_oidc | ' . $stringid, 'form-shortname d-block small text-muted');
+
+ return $formatedformitemname;
+}
+
+/**
+ * Check if the auth_oidc plugin has been configured with the minimum settings for the SSO integration to work.
+ *
+ * @return bool
+ */
+function auth_oidc_is_setup_complete() {
+ $pluginconfig = get_config('auth_oidc');
+ if (empty($pluginconfig->clientid) || empty($pluginconfig->idptype) || empty($pluginconfig->clientauthmethod)) {
+ return false;
+ }
+
+ switch ($pluginconfig->clientauthmethod) {
+ case AUTH_OIDC_AUTH_METHOD_SECRET:
+ if (empty($pluginconfig->clientsecret)) {
+ return false;
+ }
+ break;
+ case AUTH_OIDC_AUTH_METHOD_CERTIFICATE:
+ if (!isset($pluginconfig->clientcertsource)) {
+ $existingclientcertsource = get_config('auth_oidc', 'clientcertsource');
+ if ($existingclientcertsource != AUTH_OIDC_AUTH_CERT_SOURCE_TEXT) {
+ add_to_config_log('clientcertsource', $existingclientcertsource, AUTH_OIDC_AUTH_CERT_SOURCE_TEXT, 'auth_oidc');
+ }
+ set_config('clientcertsource', AUTH_OIDC_AUTH_CERT_SOURCE_TEXT, 'auth_oidc');
+ $pluginconfig->clientcertsource = AUTH_OIDC_AUTH_CERT_SOURCE_TEXT;
+ }
+ switch ($pluginconfig->clientcertsource) {
+ case AUTH_OIDC_AUTH_CERT_SOURCE_FILE:
+ if (!utils::get_certpath() || !utils::get_keypath()) {
+ return false;
+ }
+ break;
+ case AUTH_OIDC_AUTH_CERT_SOURCE_TEXT:
+ if (empty($pluginconfig->clientcert) || empty($pluginconfig->clientprivatekey)) {
+ return false;
+ }
+ break;
+ }
+ break;
+ }
+
+ if (empty($pluginconfig->authendpoint) || empty($pluginconfig->tokenendpoint)) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Return the name of the configured IdP type.
+ *
+ * @return lang_string|string
+ */
+function auth_oidc_get_idp_type_name() {
+ $idptypename = '';
+
+ switch (get_config('auth_oidc', 'idptype')) {
+ case AUTH_OIDC_IDP_TYPE_MICROSOFT_ENTRA_ID:
+ $idptypename = get_string('idp_type_microsoft_entra_id', 'auth_oidc');
+ break;
+ case AUTH_OIDC_IDP_TYPE_MICROSOFT_IDENTITY_PLATFORM:
+ $idptypename = get_string('idp_type_microsoft_identity_platform', 'auth_oidc');
+ break;
+ case AUTH_OIDC_IDP_TYPE_OTHER:
+ $idptypename = get_string('idp_type_other', 'auth_oidc');
+ break;
+ }
+
+ return $idptypename;
+}
+
+/**
+ * Return the name of the configured authentication method.
+ *
+ * @return lang_string|string
+ */
+function auth_oidc_get_client_auth_method_name() {
+ $authmethodname = '';
+
+ switch (get_config('auth_oidc', 'clientauthmethod')) {
+ case AUTH_OIDC_AUTH_METHOD_SECRET:
+ $authmethodname = get_string('auth_method_secret', 'auth_oidc');
+ break;
+ case AUTH_OIDC_AUTH_METHOD_CERTIFICATE:
+ $authmethodname = get_string('auth_method_certificate', 'auth_oidc');
+ break;
+ }
+
+ return $authmethodname;
+}
+
+/**
+ * Return the name of the configured binding username claim.
+ *
+ * @return string
+ */
+function auth_oidc_get_binding_username_claim(): string {
+ $bindingusernameclaim = get_config('auth_oidc', 'bindingusernameclaim');
+
+ if (empty($bindingusernameclaim)) {
+ $bindingusernameclaim = 'auto';
+ } else if ($bindingusernameclaim === 'custom') {
+ $bindingusernameclaim = get_config('auth_oidc', 'customclaimname');
+ } else if (!in_array($bindingusernameclaim, ['auto', 'preferred_username', 'email', 'upn', 'unique_name', 'sub', 'oid',
+ 'samaccountname'])) {
+ $bindingusernameclaim = 'auto';
+ }
+
+ return $bindingusernameclaim;
+}
+
+/**
+ * Return the claims that presents in the existing tokens.
+ *
+ * @return array
+ * @throws moodle_exception
+ */
+function auth_oidc_get_existing_claims(): array {
+ global $DB;
+
+ $sql = 'SELECT *
+ FROM {auth_oidc_token}
+ ORDER BY expiry DESC';
+ $tokenrecord = $DB->get_record_sql($sql, null, IGNORE_MULTIPLE);
+
+ $tokenclaims = [];
+
+ if ($tokenrecord) {
+ $excludedclaims = ['appid', 'appidacr', 'app_displayname', 'ipaddr', 'scp', 'tenant_region_scope', 'ver', 'aud', 'iss',
+ 'iat', 'nbf', 'exp', 'idtyp', 'plantf', 'xms_tcdt', 'xms_tdbr', 'amr', 'nonce', 'tid', 'acct', 'acr', 'signin_state',
+ 'wids'];
+
+ foreach (['idtoken', 'token'] as $tokenkey) {
+ $decodedtoken = jwt::decode($tokenrecord->$tokenkey);
+ if (is_array($decodedtoken) && count($decodedtoken) > 1) {
+ foreach ($decodedtoken[1] as $claim => $value) {
+ if (!in_array($claim, $excludedclaims) && (is_string($value) || is_numeric($value)) &&
+ !in_array($claim, $tokenclaims)) {
+ $tokenclaims[] = $claim;
+ }
+ }
+ }
+ }
+
+ asort($tokenclaims);
+ }
+
+ return $tokenclaims;
+}
+
+/**
+ * Return if the user sync feature in local_o365 plugin is enabled.
+ *
+ * @return bool|void
+ */
+function auth_oidc_is_user_sync_enabled() {
+ global $CFG;
+
+ if (auth_oidc_is_local_365_installed()) {
+ require_once($CFG->dirroot . '/local/o365/classes/feature/usersync/main.php');
+ return local_o365\feature\usersync\main::is_enabled();
+ }
+
+ return false;
+}
diff --git a/auth/oidc/logout.php b/auth/oidc/logout.php
new file mode 100644
index 00000000000..a16c8097fc9
--- /dev/null
+++ b/auth/oidc/logout.php
@@ -0,0 +1,50 @@
+.
+
+/**
+ * Single Sign Out end point.
+ *
+ * @package auth_oidc
+ * @author Lai Wei
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+// phpcs:ignore moodle.Files.RequireLogin.Missing
+require_once(__DIR__ . '/../../config.php');
+
+$PAGE->set_url('/auth/oidc/logout.php');
+$PAGE->set_context(context_system::instance());
+
+$sid = optional_param('sid', '', PARAM_TEXT);
+
+if ($sid) {
+ if ($authoidcsidrecord = $DB->get_record('auth_oidc_sid', ['sid' => $sid])) {
+ if ($authoidcsidrecord->userid == $USER->id) {
+ $authsequence = get_enabled_auth_plugins(); // Auths, in sequence.
+ foreach ($authsequence as $authname) {
+ $authplugin = get_auth_plugin($authname);
+ $authplugin->logoutpage_hook();
+ }
+
+ $DB->delete_records('auth_oidc_sid', ['sid' => $sid]);
+ require_logout();
+ redirect($redirect);
+ }
+ }
+}
+
+die();
diff --git a/auth/oidc/manageapplication.php b/auth/oidc/manageapplication.php
new file mode 100644
index 00000000000..401b8881366
--- /dev/null
+++ b/auth/oidc/manageapplication.php
@@ -0,0 +1,150 @@
+.
+
+/**
+ * OIDC application configuration page.
+ *
+ * @package auth_oidc
+ * @author Lai Wei
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2022 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+use auth_oidc\form\application;
+
+require_once(dirname(__FILE__) . '/../../config.php');
+require_once($CFG->libdir . '/adminlib.php');
+require_once($CFG->dirroot . '/auth/oidc/lib.php');
+
+require_login();
+
+$url = new moodle_url('/auth/oidc/manageapplication.php');
+$PAGE->set_url($url);
+$PAGE->set_context(context_system::instance());
+$PAGE->set_pagelayout('admin');
+$PAGE->set_heading(get_string('settings_page_application', 'auth_oidc'));
+$PAGE->set_title(get_string('settings_page_application', 'auth_oidc'));
+
+$jsparams = [AUTH_OIDC_IDP_TYPE_MICROSOFT_IDENTITY_PLATFORM, AUTH_OIDC_AUTH_METHOD_SECRET, AUTH_OIDC_AUTH_METHOD_CERTIFICATE,
+ get_string('auth_method_certificate', 'auth_oidc')];
+$jsmodule = [
+ 'name' => 'auth_oidc',
+ 'fullpath' => '/auth/oidc/js/module.js',
+];
+$PAGE->requires->js_init_call('M.auth_oidc.init', $jsparams, true, $jsmodule);
+
+admin_externalpage_setup('auth_oidc_application');
+
+require_admin();
+
+$oidcconfig = get_config('auth_oidc');
+
+$form = new application(null, ['oidcconfig' => $oidcconfig]);
+
+$formdata = [];
+foreach (['idptype', 'clientid', 'clientauthmethod', 'clientsecret', 'clientprivatekey', 'clientcert',
+ 'clientcertsource', 'clientprivatekeyfile', 'clientcertfile', 'clientcertpassphrase',
+ 'authendpoint', 'tokenendpoint', 'oidcresource', 'oidcscope', 'secretexpiryrecipients',
+ 'bindingusernameclaim', 'customclaimname'] as $field) {
+ if (isset($oidcconfig->$field)) {
+ $formdata[$field] = $oidcconfig->$field;
+ }
+}
+
+$form->set_data($formdata);
+
+if ($form->is_cancelled()) {
+ redirect($url);
+} else if ($fromform = $form->get_data()) {
+ // Handle odd cases where clientauthmethod is not received.
+ if (!isset($fromform->clientauthmethod)) {
+ $fromform->clientauthmethod = optional_param('clientauthmethod', AUTH_OIDC_AUTH_METHOD_SECRET, PARAM_INT);
+ }
+
+ // Prepare config settings to save.
+ $configstosave = ['idptype', 'clientid', 'clientauthmethod', 'authendpoint', 'tokenendpoint',
+ 'oidcresource', 'oidcscope'];
+
+ // Depending on the value of clientauthmethod, save clientsecret or (clientprivatekey and clientcert).
+ switch ($fromform->clientauthmethod) {
+ case AUTH_OIDC_AUTH_METHOD_SECRET:
+ $configstosave[] = 'clientsecret';
+ $configstosave[] = 'secretexpiryrecipients';
+ break;
+ case AUTH_OIDC_AUTH_METHOD_CERTIFICATE:
+ $configstosave[] = 'clientcertsource';
+ $configstosave[] = 'clientcertpassphrase';
+ switch ($fromform->clientcertsource) {
+ case AUTH_OIDC_AUTH_CERT_SOURCE_TEXT:
+ $configstosave[] = 'clientprivatekey';
+ $configstosave[] = 'clientcert';
+ break;
+ case AUTH_OIDC_AUTH_CERT_SOURCE_FILE:
+ $configstosave[] = 'clientprivatekeyfile';
+ $configstosave[] = 'clientcertfile';
+ break;
+ }
+ break;
+ }
+
+ // Save config settings.
+ $updateapplicationtokenrequired = false;
+ $settingschanged = false;
+ foreach ($configstosave as $config) {
+ $existingsetting = get_config('auth_oidc', $config);
+ if ($fromform->$config != $existingsetting) {
+ add_to_config_log($config, $existingsetting, $fromform->$config, 'auth_oidc');
+ set_config($config, $fromform->$config, 'auth_oidc');
+ $settingschanged = true;
+ if ($config != 'secretexpiryrecipients') {
+ $updateapplicationtokenrequired = true;
+ }
+ }
+ }
+
+ // Redirect destination and message depend on IdP type.
+ $isgraphapiconnected = false;
+ if ($fromform->idptype != AUTH_OIDC_IDP_TYPE_OTHER) {
+ if (auth_oidc_is_local_365_installed()) {
+ $isgraphapiconnected = true;
+ }
+ }
+
+ if ($updateapplicationtokenrequired) {
+ if ($isgraphapiconnected) {
+ // First, delete the existing application token and purge cache.
+ unset_config('apptokens', 'local_o365');
+ unset_config('azuresetupresult', 'local_o365');
+ purge_all_caches();
+
+ // Then show the message to the user with instructions to update the application token.
+ $localo365configurl = new moodle_url('/admin/settings.php', ['section' => 'local_o365']);
+ redirect($localo365configurl, get_string('application_updated_microsoft', 'auth_oidc'));
+ } else {
+ redirect($url, get_string('application_updated', 'auth_oidc'));
+ }
+ } else if ($settingschanged) {
+ redirect($url, get_string('application_updated', 'auth_oidc'));
+ } else {
+ redirect($url, get_string('application_not_changed', 'auth_oidc'));
+ }
+}
+
+echo $OUTPUT->header();
+
+$form->display();
+
+echo $OUTPUT->footer();
diff --git a/auth/oidc/pix/o365.png b/auth/oidc/pix/o365.png
new file mode 100644
index 00000000000..0fa022c25ea
Binary files /dev/null and b/auth/oidc/pix/o365.png differ
diff --git a/auth/oidc/settings.php b/auth/oidc/settings.php
new file mode 100644
index 00000000000..121db834608
--- /dev/null
+++ b/auth/oidc/settings.php
@@ -0,0 +1,258 @@
+.
+
+/**
+ * Plugin settings.
+ *
+ * @package auth_oidc
+ * @author James McQuillan
+ * @author Lai Wei
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+use auth_oidc\adminsetting\auth_oidc_admin_setting_iconselect;
+use auth_oidc\adminsetting\auth_oidc_admin_setting_loginflow;
+use auth_oidc\adminsetting\auth_oidc_admin_setting_redirecturi;
+use auth_oidc\utils;
+
+require_once($CFG->dirroot . '/auth/oidc/lib.php');
+
+if ($hassiteconfig) {
+ // Add folder for OIDC settings.
+ $oidcfolder = new admin_category('oidcfolder', get_string('pluginname', 'auth_oidc'));
+ $ADMIN->add('authsettings', $oidcfolder);
+
+ // Application configuration page.
+ $ADMIN->add('oidcfolder', new admin_externalpage('auth_oidc_application', get_string('settings_page_application', 'auth_oidc'),
+ new moodle_url('/auth/oidc/manageapplication.php')));
+
+
+ $idptype = get_config('auth_oidc', 'idptype');
+ if ($idptype) {
+ // Binding username claim page.
+ $ADMIN->add('oidcfolder', new admin_externalpage('auth_oidc_binding_username_claim',
+ get_string('settings_page_binding_username_claim', 'auth_oidc'),
+ new moodle_url('/auth/oidc/binding_username_claim.php')));
+
+ // Change binding username claim tool page.
+ $ADMIN->add('oidcfolder', new admin_externalpage('auth_oidc_change_binding_username_claim_tool',
+ get_string('settings_page_change_binding_username_claim_tool', 'auth_oidc'),
+ new moodle_url('/auth/oidc/change_binding_username_claim_tool.php')));
+ }
+
+
+ // Other settings page and its settings.
+ $settings = new admin_settingpage($section, get_string('settings_page_other_settings', 'auth_oidc'));
+
+ // Basic heading.
+ $settings->add(new admin_setting_heading('auth_oidc/basic_heading', get_string('heading_basic', 'auth_oidc'),
+ get_string('heading_basic_desc', 'auth_oidc')));
+
+ // Redirect URI.
+ $settings->add(new auth_oidc_admin_setting_redirecturi('auth_oidc/redirecturi',
+ get_string('cfg_redirecturi_key', 'auth_oidc'), get_string('cfg_redirecturi_desc', 'auth_oidc'), utils::get_redirecturl()));
+
+ // Link to authentication options.
+ $authenticationconfigurationurl = new moodle_url('/auth/oidc/manageapplication.php');
+ $settings->add(new admin_setting_description('auth_oidc/authenticationlink',
+ get_string('settings_page_application', 'auth_oidc'),
+ get_string('cfg_authenticationlink_desc', 'auth_oidc', $authenticationconfigurationurl->out())));
+
+ // Additional options heading.
+ $settings->add(new admin_setting_heading('auth_oidc/additional_options_heading',
+ get_string('heading_additional_options', 'auth_oidc'), get_string('heading_additional_options_desc', 'auth_oidc')));
+
+ // Force redirect.
+ $settings->add(new admin_setting_configcheckbox('auth_oidc/forceredirect',
+ get_string('cfg_forceredirect_key', 'auth_oidc'), get_string('cfg_forceredirect_desc', 'auth_oidc'), 0));
+
+ // Silent login mode.
+ $forceloginconfigurl = new moodle_url('/admin/settings.php', ['section' => 'sitepolicies']);
+ $settings->add(new admin_setting_configcheckbox('auth_oidc/silentloginmode',
+ get_string('cfg_silentloginmode_key', 'auth_oidc'),
+ get_string('cfg_silentloginmode_desc', 'auth_oidc', $forceloginconfigurl->out(false)), 0));
+
+ // Auto-append.
+ $settings->add(new admin_setting_configtext('auth_oidc/autoappend',
+ get_string('cfg_autoappend_key', 'auth_oidc'), get_string('cfg_autoappend_desc', 'auth_oidc'), '', PARAM_TEXT));
+
+ // Domain hint.
+ $settings->add(new admin_setting_configtext('auth_oidc/domainhint',
+ get_string('cfg_domainhint_key', 'auth_oidc'), get_string('cfg_domainhint_desc', 'auth_oidc'), '' , PARAM_TEXT));
+
+ // Login flow.
+ $settings->add(new auth_oidc_admin_setting_loginflow('auth_oidc/loginflow',
+ get_string('cfg_loginflow_key', 'auth_oidc'), '', 'authcode'));
+
+ // User restrictions heading.
+ $settings->add(new admin_setting_heading('auth_oidc/user_restrictions_heading',
+ get_string('heading_user_restrictions', 'auth_oidc'), get_string('heading_user_restrictions_desc', 'auth_oidc')));
+
+ // User restrictions.
+ $settings->add(new admin_setting_configtextarea('auth_oidc/userrestrictions',
+ get_string('cfg_userrestrictions_key', 'auth_oidc'), get_string('cfg_userrestrictions_desc', 'auth_oidc'), '', PARAM_TEXT));
+
+ // User restrictions case sensitivity.
+ $settings->add(new admin_setting_configcheckbox('auth_oidc/userrestrictionscasesensitive',
+ get_string('cfg_userrestrictionscasesensitive_key', 'auth_oidc'),
+ get_string('cfg_userrestrictionscasesensitive_desc', 'auth_oidc'), '1'));
+
+ // Sign out integration heading.
+ $settings->add(new admin_setting_heading('auth_oidc/sign_out_heading',
+ get_string('heading_sign_out', 'auth_oidc'), get_string('heading_sign_out_desc', 'auth_oidc')));
+
+ // Single sign out from Moodle to IdP.
+ $settings->add(new admin_setting_configcheckbox('auth_oidc/single_sign_off',
+ get_string('cfg_signoffintegration_key', 'auth_oidc'),
+ get_string('cfg_signoffintegration_desc', 'auth_oidc', $CFG->wwwroot), '0'));
+
+ // IdP logout endpoint.
+ $settings->add(new admin_setting_configtext('auth_oidc/logouturi',
+ get_string('cfg_logoutendpoint_key', 'auth_oidc'), get_string('cfg_logoutendpoint_desc', 'auth_oidc'),
+ 'https://login.microsoftonline.com/organizations/oauth2/logout', PARAM_URL));
+
+ // Front channel logout URL.
+ $settings->add(new auth_oidc_admin_setting_redirecturi('auth_oidc/logoutendpoint',
+ get_string('cfg_frontchannellogouturl_key', 'auth_oidc'), get_string('cfg_frontchannellogouturl_desc', 'auth_oidc'),
+ utils::get_frontchannellogouturl()));
+
+ // Display heading.
+ $settings->add(new admin_setting_heading('auth_oidc/display_heading',
+ get_string('heading_display', 'auth_oidc'), get_string('heading_display_desc', 'auth_oidc')));
+
+ // Provider Name (opname).
+ $settings->add(new admin_setting_configtext('auth_oidc/opname',
+ get_string('cfg_opname_key', 'auth_oidc'), get_string('cfg_opname_desc', 'auth_oidc'),
+ get_string('pluginname', 'auth_oidc'), PARAM_TEXT));
+
+ // Icon.
+ $icons = [
+ [
+ 'pix' => 'o365',
+ 'alt' => new lang_string('cfg_iconalt_o365', 'auth_oidc'),
+ 'component' => 'auth_oidc',
+ ],
+ [
+ 'pix' => 't/locked',
+ 'alt' => new lang_string('cfg_iconalt_locked', 'auth_oidc'),
+ 'component' => 'moodle',
+ ],
+ [
+ 'pix' => 't/lock',
+ 'alt' => new lang_string('cfg_iconalt_lock', 'auth_oidc'),
+ 'component' => 'moodle',
+ ],
+ [
+ 'pix' => 't/go',
+ 'alt' => new lang_string('cfg_iconalt_go', 'auth_oidc'),
+ 'component' => 'moodle',
+ ],
+ [
+ 'pix' => 't/stop',
+ 'alt' => new lang_string('cfg_iconalt_stop', 'auth_oidc'),
+ 'component' => 'moodle',
+ ],
+ [
+ 'pix' => 't/user',
+ 'alt' => new lang_string('cfg_iconalt_user', 'auth_oidc'),
+ 'component' => 'moodle',
+ ],
+ [
+ 'pix' => 'u/user35',
+ 'alt' => new lang_string('cfg_iconalt_user2', 'auth_oidc'),
+ 'component' => 'moodle',
+ ],
+ [
+ 'pix' => 'i/permissions',
+ 'alt' => new lang_string('cfg_iconalt_key', 'auth_oidc'),
+ 'component' => 'moodle',
+ ],
+ [
+ 'pix' => 'i/cohort',
+ 'alt' => new lang_string('cfg_iconalt_group', 'auth_oidc'),
+ 'component' => 'moodle',
+ ],
+ [
+ 'pix' => 'i/groups',
+ 'alt' => new lang_string('cfg_iconalt_group2', 'auth_oidc'),
+ 'component' => 'moodle',
+ ],
+ [
+ 'pix' => 'i/mnethost',
+ 'alt' => new lang_string('cfg_iconalt_mnet', 'auth_oidc'),
+ 'component' => 'moodle',
+ ],
+ [
+ 'pix' => 'i/permissionlock',
+ 'alt' => new lang_string('cfg_iconalt_userlock', 'auth_oidc'),
+ 'component' => 'moodle',
+ ],
+ [
+ 'pix' => 't/more',
+ 'alt' => new lang_string('cfg_iconalt_plus', 'auth_oidc'),
+ 'component' => 'moodle',
+ ],
+ [
+ 'pix' => 't/approve',
+ 'alt' => new lang_string('cfg_iconalt_check', 'auth_oidc'),
+ 'component' => 'moodle',
+ ],
+ [
+ 'pix' => 't/right',
+ 'alt' => new lang_string('cfg_iconalt_rightarrow', 'auth_oidc'),
+ 'component' => 'moodle',
+ ],
+ ];
+ $settings->add(new auth_oidc_admin_setting_iconselect('auth_oidc/icon',
+ get_string('cfg_icon_key', 'auth_oidc'), get_string('cfg_icon_desc', 'auth_oidc'), 'auth_oidc:o365', $icons));
+
+ // Custom icon.
+ $configkey = new lang_string('cfg_customicon_key', 'auth_oidc');
+ $configdesc = new lang_string('cfg_customicon_desc', 'auth_oidc');
+ $customiconsetting = new admin_setting_configstoredfile('auth_oidc/customicon',
+ get_string('cfg_customicon_key', 'auth_oidc'), get_string('cfg_customicon_desc', 'auth_oidc'), 'customicon', 0,
+ ['accepted_types' => ['.png', '.jpg', '.ico'], 'maxbytes' => get_max_upload_file_size()]);
+ $customiconsetting->set_updatedcallback('auth_oidc_initialize_customicon');
+ $settings->add($customiconsetting);
+
+ // Debugging heading.
+ $settings->add(new admin_setting_heading('auth_oidc/debugging_heading',
+ get_string('heading_debugging', 'auth_oidc'), get_string('heading_debugging_desc', 'auth_oidc')));
+
+ // Record debugging messages.
+ $settings->add(new admin_setting_configcheckbox('auth_oidc/debugmode',
+ get_string('cfg_debugmode_key', 'auth_oidc'), get_string('cfg_debugmode_desc', 'auth_oidc'), '0'));
+
+ $ADMIN->add('oidcfolder', $settings);
+
+ // Cleanup OIDC tokens page.
+ $ADMIN->add('oidcfolder', new admin_externalpage('auth_oidc_cleanup_oidc_tokens',
+ get_string('settings_page_cleanup_oidc_tokens', 'auth_oidc'), new moodle_url('/auth/oidc/cleanupoidctokens.php')));
+
+ // Other settings page and its settings.
+ $fieldmappingspage = new admin_settingpage('auth_oidc_field_mapping', get_string('settings_page_field_mapping', 'auth_oidc'));
+ $ADMIN->add('oidcfolder', $fieldmappingspage);
+
+ // Display locking / mapping of profile fields.
+ $authplugin = get_auth_plugin('oidc');
+ auth_oidc_display_auth_lock_options($fieldmappingspage, $authplugin->authtype, $authplugin->userfields,
+ get_string('cfg_field_mapping_desc', 'auth_oidc'), true, false, $authplugin->get_custom_user_profile_fields());
+}
+
+$settings = null;
diff --git a/auth/oidc/styles.css b/auth/oidc/styles.css
new file mode 100644
index 00000000000..077b53e3176
--- /dev/null
+++ b/auth/oidc/styles.css
@@ -0,0 +1,49 @@
+.auth_oidc_ucp_indicator h4 {
+ display: inline-block;
+ margin-right: 0.5rem;
+}
+
+.auth_oidc_ucp_indicator h5 {
+ display: inline-block;
+ margin-left: 0.5rem;
+}
+
+.auth_oidc_ucp_indicator h5 + span {
+ display: block;
+}
+
+.cert_textarea textarea {
+ font-family: 'Courier New', Courier, monospace;
+}
+
+.path-admin-auth-oidc .warning_header {
+ border: 1px solid #f00;
+ background-color: #ffe5e5;
+ padding: 10px;
+ margin: 10px 0;
+ color: #f00;
+ font-weight: bold;
+}
+
+.path-admin-auth-oidc .warning {
+ color: #f00;
+ font-weight: bold;
+}
+
+.path-admin-auth-oidc .existing_claims {
+ display: inline-block;
+ background-color: #f0f0f0;
+ border: 1px solid #ccc;
+ padding: 10px;
+ font-family: 'Courier New', Courier, monospace;
+ white-space: pre;
+}
+
+.path-admin-auth-oidc .not_support_user_sync {
+ color: #f00;
+}
+
+.path-admin-auth-oidc .code {
+ font-family: 'Courier New', Courier, monospace;
+ white-space: pre;
+}
diff --git a/auth/oidc/tests/jwt_test.php b/auth/oidc/tests/jwt_test.php
new file mode 100644
index 00000000000..2eb99095b6e
--- /dev/null
+++ b/auth/oidc/tests/jwt_test.php
@@ -0,0 +1,132 @@
+.
+
+/**
+ * JWT test cases.
+ *
+ * @package auth_oidc
+ * @author James McQuillan
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+namespace auth_oidc;
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+
+/**
+ * Tests jwt.
+ *
+ * @group auth_oidc
+ * @group office365
+ */
+final class jwt_test extends \advanced_testcase {
+ /**
+ * Perform setup before every test. This tells Moodle's phpunit to reset the database after every test.
+ */
+ protected function setUp(): void {
+ parent::setUp();
+ $this->resetAfterTest(true);
+ }
+
+ /**
+ * Dataprovider for test_decode.
+ *
+ * @return array Array of arrays of test parameters.
+ */
+ public static function dataprovider_decode(): array {
+ $tests = [];
+
+ $tests['emptytest'] = [
+ '', '', ['Exception', 'Empty or non-string JWT received.'],
+ ];
+
+ $tests['nonstringtest'] = [
+ 100, '', ['Exception', 'Empty or non-string JWT received.'],
+ ];
+
+ $tests['malformed1'] = [
+ 'a', '', ['Exception', 'Malformed JWT received.'],
+ ];
+
+ $tests['malformed2'] = [
+ 'a.b', '', ['Exception', 'Malformed JWT received.'],
+ ];
+
+ $tests['malformed3'] = [
+ 'a.b.c.d', '', ['Exception', 'Malformed JWT received.'],
+ ];
+
+ $tests['badheader1'] = [
+ 'h.p.s', '', ['Exception', 'Could not read JWT header'],
+ ];
+
+ $header = base64_encode(json_encode(['key' => 'val']));
+ $tests['invalidheader1'] = [
+ $header . '.p.s', '', ['Exception', 'Invalid JWT header'],
+ ];
+
+ $header = base64_encode(json_encode(['alg' => 'ROT13']));
+ $tests['badalg1'] = [
+ $header . '.p.s', '', ['Exception', 'JWS Alg or JWE not supported'],
+ ];
+
+ $header = base64_encode(json_encode(['alg' => 'RS256']));
+ $payload = 'p';
+ $tests['badpayload1'] = [
+ $header . '.' . $payload . '.s', '', ['Exception', 'Could not read JWT payload.'],
+ ];
+
+ $header = base64_encode(json_encode(['alg' => 'RS256']));
+ $payload = base64_encode('nothing');
+ $tests['badpayload2'] = [
+ $header . '.' . $payload . '.s', '', ['Exception', 'Could not read JWT payload.'],
+ ];
+
+ $header = ['alg' => 'RS256'];
+ $payload = ['payload' => 'found'];
+ $headerenc = base64_encode(json_encode($header));
+ $payloadenc = base64_encode(json_encode($payload));
+ $expected = [$header, $payload];
+ $tests['goodpayload1'] = [
+ $headerenc . '.' . $payloadenc . '.s', $expected, [],
+ ];
+
+ return $tests;
+ }
+
+ /**
+ * Test decode.
+ *
+ * @dataProvider dataprovider_decode
+ * @covers \auth_oidc\jwt::decode
+ *
+ * @param string $encodedjwt The JWT token to be decoded.
+ * @param mixed $expectedresult The expected result after decoding.
+ * @param array $expectedexception The expected exception class and message if an error occurs.
+ * @return void
+ */
+ public function test_decode($encodedjwt, $expectedresult, $expectedexception): void {
+ if (!empty($expectedexception)) {
+ $this->expectException($expectedexception[0]);
+ $this->expectExceptionMessage($expectedexception[1]);
+ }
+ $actualresult = \auth_oidc\jwt::decode($encodedjwt);
+ $this->assertEquals($expectedresult, $actualresult);
+ }
+}
diff --git a/auth/oidc/tests/oidcclient_test.php b/auth/oidc/tests/oidcclient_test.php
new file mode 100644
index 00000000000..47e2a41182f
--- /dev/null
+++ b/auth/oidc/tests/oidcclient_test.php
@@ -0,0 +1,132 @@
+.
+
+/**
+ * OIDC client test cases.
+ *
+ * @package auth_oidc
+ * @author James McQuillan
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+
+
+namespace auth_oidc;
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+
+/**
+ * Tests oidcclient.
+ *
+ * @group auth_oidc
+ * @group office365
+ */
+final class oidcclient_test extends \advanced_testcase {
+ /**
+ * Perform setup before every test. This tells Moodle's phpunit to reset the database after every test.
+ */
+ protected function setUp(): void {
+ parent::setUp();
+ $this->resetAfterTest(true);
+ }
+
+ /**
+ * Test getting and setting credentials.
+ *
+ * @covers \auth_oidc\tests\mockoidcclient::setcreds
+ */
+ public function test_creds_getters_and_setters(): void {
+ $httpclient = new \auth_oidc\tests\mockhttpclient();
+ $client = new \auth_oidc\tests\mockoidcclient($httpclient);
+
+ $this->assertNull($client->get_clientid());
+ $this->assertNull($client->get_clientsecret());
+ $this->assertNull($client->get_redirecturi());
+
+ $id = 'id';
+ $secret = 'secret';
+ $redirecturi = 'redirecturi';
+ $tokenresource = 'resource';
+ $scope = (isset($this->config->oidcscope)) ? $this->config->oidcscope : null;
+ $client->setcreds($id, $secret, $redirecturi, $tokenresource, $scope);
+
+ $this->assertEquals($id, $client->get_clientid());
+ $this->assertEquals($secret, $client->get_clientsecret());
+ $this->assertEquals($redirecturi, $client->get_redirecturi());
+ $this->assertEquals($tokenresource, $client->get_tokenresource());
+ }
+
+ /**
+ * Dataprovider returning endpoints.
+ *
+ * @return array Array of arrays of test parameters.
+ */
+ public static function dataprovider_endpoints(): array {
+ $tests = [];
+
+ $tests['oneinvalid'] = [
+ ['auth' => 100],
+ ['Exception', 'Invalid Endpoint URI received.'],
+ ];
+
+ $tests['oneinvalidonevalid1'] = [
+ ['auth' => 100, 'token' => 'http://example.com/token'],
+ ['Exception', 'Invalid Endpoint URI received.'],
+ ];
+
+ $tests['oneinvalidonevalid2'] = [
+ ['token' => 'http://example.com/token', 'auth' => 100],
+ ['Exception', 'Invalid Endpoint URI received.'],
+ ];
+
+ $tests['onevalid'] = [
+ ['token' => 'http://example.com/token'],
+ [],
+ ];
+
+ $tests['twovalid'] = [
+ ['auth' => 'http://example.com/auth', 'token' => 'http://example.com/token'],
+ [],
+ ];
+
+ return $tests;
+ }
+
+ /**
+ * Test setting and getting endpoints.
+ *
+ * @dataProvider dataprovider_endpoints
+ * @covers \auth_oidc\tests\mockoidcclient::setendpoints
+ * @param array $endpoints
+ * @param array $expectedexception
+ */
+ public function test_endpoints_getters_and_setters(array $endpoints, array $expectedexception): void {
+ if (!empty($expectedexception)) {
+ $this->expectException($expectedexception[0]);
+ $this->expectExceptionMessage($expectedexception[1]);
+ }
+ $httpclient = new \auth_oidc\tests\mockhttpclient();
+ $client = new \auth_oidc\tests\mockoidcclient($httpclient);
+ $client->setendpoints($endpoints);
+
+ foreach ($endpoints as $type => $uri) {
+ $this->assertEquals($uri, $client->get_endpoint($type));
+ }
+ }
+}
diff --git a/auth/oidc/tests/privacy_provider_test.php b/auth/oidc/tests/privacy_provider_test.php
new file mode 100644
index 00000000000..6a3989c2dc2
--- /dev/null
+++ b/auth/oidc/tests/privacy_provider_test.php
@@ -0,0 +1,314 @@
+.
+
+/**
+ * Privacy test for auth_oidc
+ *
+ * @package auth_oidc
+ * @author Remote-Learner.net Inc
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2019 Remote Learner.net Inc http://www.remote-learner.net
+ */
+
+namespace auth_oidc;
+
+use auth_oidc\privacy\provider;
+
+/**
+ * Privacy test for auth_oidc
+ *
+ * @group auth_oidc
+ * @group auth_oidc_privacy
+ * @group office365
+ * @group office365_privacy
+ */
+final class privacy_provider_test extends \core_privacy\tests\provider_testcase {
+
+ /**
+ * Tests set up.
+ */
+ public function setUp(): void {
+ parent::setUp();
+ $this->resetAfterTest();
+ $this->setAdminUser();
+ }
+
+ /**
+ * Check that a user context is returned if there is any user data for this user.
+ *
+ * @covers \auth_oidc\privacy\provider::get_contexts_for_userid
+ */
+ public function test_get_contexts_for_userid(): void {
+ $user = $this->getDataGenerator()->create_user();
+ $this->assertEmpty(provider::get_contexts_for_userid($user->id));
+
+ // Create user records.
+ self::create_token($user->id);
+ self::create_prevlogin($user->id);
+
+ $contextlist = provider::get_contexts_for_userid($user->id);
+ // Check that we only get back one context.
+ $this->assertCount(1, $contextlist);
+
+ // Check that a context is returned and is the expected context.
+ $usercontext = \context_user::instance($user->id);
+ $this->assertEquals($usercontext->id, $contextlist->get_contextids()[0]);
+ }
+
+ /**
+ * Test that only users with a user context are fetched.
+ *
+ * @covers \auth_oidc\privacy\provider::get_users_in_context
+ */
+ public function test_get_users_in_context(): void {
+ $this->resetAfterTest();
+
+ $component = 'auth_oidc';
+ // Create a user.
+ $user = $this->getDataGenerator()->create_user();
+ $usercontext = \context_user::instance($user->id);
+
+ // The list of users should not return anything yet (related data still haven't been created).
+ $userlist = new \core_privacy\local\request\userlist($usercontext, $component);
+ provider::get_users_in_context($userlist);
+ $this->assertCount(0, $userlist);
+
+ // Create user records.
+ self::create_token($user->id);
+ self::create_prevlogin($user->id);
+
+ // The list of users for user context should return the user.
+ provider::get_users_in_context($userlist);
+ $this->assertCount(1, $userlist);
+ $expected = [$user->id];
+ $actual = $userlist->get_userids();
+ $this->assertEquals($expected, $actual);
+
+ // The list of users for system context should not return any users.
+ $userlist = new \core_privacy\local\request\userlist(\context_system::instance(), $component);
+ provider::get_users_in_context($userlist);
+ $this->assertCount(0, $userlist);
+ }
+
+ /**
+ * Test that user data is exported correctly.
+ *
+ * @covers \auth_oidc\privacy\provider::export_user_data
+ */
+ public function test_export_user_data(): void {
+ // Create a user record.
+ $user = $this->getDataGenerator()->create_user();
+ $tokenrecord = self::create_token($user->id);
+ $prevloginrecord = self::create_prevlogin($user->id);
+
+ $usercontext = \context_user::instance($user->id);
+
+ $writer = \core_privacy\local\request\writer::with_context($usercontext);
+ $this->assertFalse($writer->has_any_data());
+ $approvedlist = new \core_privacy\local\request\approved_contextlist($user, 'auth_oidc', [$usercontext->id]);
+ provider::export_user_data($approvedlist);
+ // Token.
+ $data = $writer->get_data([
+ get_string('privacy:metadata:auth_oidc', 'auth_oidc'),
+ get_string('privacy:metadata:auth_oidc_token', 'auth_oidc'),
+ ]);
+ $this->assertEquals($tokenrecord->userid, $data->userid);
+ $this->assertEquals($tokenrecord->token, $data->token);
+ // Previous login.
+ $data = $writer->get_data([
+ get_string('privacy:metadata:auth_oidc', 'auth_oidc'),
+ get_string('privacy:metadata:auth_oidc_prevlogin', 'auth_oidc'),
+ ]);
+ $this->assertEquals($prevloginrecord->userid, $data->userid);
+ $this->assertEquals($prevloginrecord->method, $data->method);
+ $this->assertEquals($prevloginrecord->password, $data->password);
+ }
+
+ /**
+ * Test deleting all user data for a specific context.
+ *
+ * @covers \auth_oidc\privacy\provider::delete_data_for_all_users_in_context
+ */
+ public function test_delete_data_for_all_users_in_context(): void {
+ global $DB;
+
+ // Create a user record.
+ $user1 = $this->getDataGenerator()->create_user();
+ self::create_token($user1->id);
+ self::create_prevlogin($user1->id);
+ $user1context = \context_user::instance($user1->id);
+
+ $user2 = $this->getDataGenerator()->create_user();
+ self::create_token($user2->id);
+ self::create_prevlogin($user2->id);
+
+ // Get all accounts. There should be two.
+ $this->assertCount(2, $DB->get_records('auth_oidc_token', []));
+ $this->assertCount(2, $DB->get_records('auth_oidc_prevlogin', []));
+
+ // Delete everything for the first user context.
+ provider::delete_data_for_all_users_in_context($user1context);
+
+ $this->assertCount(0, $DB->get_records('auth_oidc_token', ['userid' => $user1->id]));
+ $this->assertCount(0, $DB->get_records('auth_oidc_prevlogin', ['userid' => $user1->id]));
+
+ // Get all accounts. There should be one.
+ $this->assertCount(1, $DB->get_records('auth_oidc_token', []));
+ $this->assertCount(1, $DB->get_records('auth_oidc_prevlogin', []));
+ }
+
+ /**
+ * This should work identical to the above test.
+ *
+ * @covers \auth_oidc\privacy\provider::delete_data_for_user
+ */
+ public function test_delete_data_for_user(): void {
+ global $DB;
+
+ // Create a user record.
+ $user1 = $this->getDataGenerator()->create_user();
+ self::create_token($user1->id);
+ self::create_prevlogin($user1->id);
+ $user1context = \context_user::instance($user1->id);
+
+ $user2 = $this->getDataGenerator()->create_user();
+ self::create_token($user2->id);
+ self::create_prevlogin($user2->id);
+
+ // Get all accounts. There should be two.
+ $this->assertCount(2, $DB->get_records('auth_oidc_token', []));
+ $this->assertCount(2, $DB->get_records('auth_oidc_prevlogin', []));
+
+ // Delete everything for the first user.
+ $approvedlist = new \core_privacy\local\request\approved_contextlist($user1, 'auth_oidc', [$user1context->id]);
+ provider::delete_data_for_user($approvedlist);
+
+ $this->assertCount(0, $DB->get_records('auth_oidc_token', ['userid' => $user1->id]));
+ $this->assertCount(0, $DB->get_records('auth_oidc_prevlogin', ['userid' => $user1->id]));
+
+ // Get all accounts. There should be one.
+ $this->assertCount(1, $DB->get_records('auth_oidc_token', []));
+ $this->assertCount(1, $DB->get_records('auth_oidc_prevlogin', []));
+ }
+
+ /**
+ * Test that data for users in approved userlist is deleted.
+ *
+ * @covers \auth_oidc\privacy\provider::delete_data_for_users
+ */
+ public function test_delete_data_for_users(): void {
+ $this->resetAfterTest();
+
+ $component = 'auth_oidc';
+ // Create user1.
+ $user1 = $this->getDataGenerator()->create_user();
+ $usercontext1 = \context_user::instance($user1->id);
+ self::create_token($user1->id);
+ self::create_prevlogin($user1->id);
+
+ // Create user2.
+ $user2 = $this->getDataGenerator()->create_user();
+ $usercontext2 = \context_user::instance($user2->id);
+ self::create_token($user2->id);
+ self::create_prevlogin($user2->id);
+
+ // The list of users for usercontext1 should return user1.
+ $userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component);
+ provider::get_users_in_context($userlist1);
+ $this->assertCount(1, $userlist1);
+ $expected = [$user1->id];
+ $actual = $userlist1->get_userids();
+ $this->assertEquals($expected, $actual);
+
+ // The list of users for usercontext2 should return user2.
+ $userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component);
+ provider::get_users_in_context($userlist2);
+ $this->assertCount(1, $userlist2);
+ $expected = [$user2->id];
+ $actual = $userlist2->get_userids();
+ $this->assertEquals($expected, $actual);
+
+ // Add userlist1 to the approved user list.
+ $approvedlist = new \core_privacy\local\request\approved_userlist($usercontext1, $component, $userlist1->get_userids());
+
+ // Delete user data using delete_data_for_user for usercontext1.
+ provider::delete_data_for_users($approvedlist);
+
+ // Re-fetch users in usercontext1 - The user list should now be empty.
+ $userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component);
+ provider::get_users_in_context($userlist1);
+ $this->assertCount(0, $userlist1);
+ // Re-fetch users in usercontext2 - The user list should not be empty (user2).
+ $userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component);
+ provider::get_users_in_context($userlist2);
+ $this->assertCount(1, $userlist2);
+
+ // User data should be only removed in the user context.
+ $systemcontext = \context_system::instance();
+ // Add userlist2 to the approved user list in the system context.
+ $approvedlist = new \core_privacy\local\request\approved_userlist($systemcontext, $component, $userlist2->get_userids());
+ // Delete user1 data using delete_data_for_user.
+ provider::delete_data_for_users($approvedlist);
+ // Re-fetch users in usercontext2 - The user list should not be empty (user2).
+ $userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component);
+ provider::get_users_in_context($userlist2);
+ $this->assertCount(1, $userlist2);
+ }
+
+ /**
+ * Create a token record for the specified userid.
+ *
+ * @param int $userid
+ * @return \stdClass
+ * @throws \dml_exception
+ */
+ private static function create_token(int $userid): \stdClass {
+ global $DB;
+ $record = new \stdClass();
+ $record->oidcuniqid = "user@example.com";
+ $record->username = "user@example.com";
+ $record->userid = $userid;
+ $record->oidcusername = "user@example.com";
+ $record->useridentifier = "user@example.com";
+ $record->scope = "All";
+ $record->tokenresource = "https://graph.microsoft.com";
+ $record->authcode = "authcode123";
+ $record->token = "token123";
+ $record->expiry = 12345;
+ $record->refreshtoken = "refresh123";
+ $record->idtoken = "idtoken123";
+ $record->id = $DB->insert_record('auth_oidc_token', $record);
+ return $record;
+ }
+
+ /**
+ * Create a previous login record for the specified userid.
+ *
+ * @param int $userid
+ * @return \stdClass
+ * @throws \dml_exception
+ */
+ private static function create_prevlogin(int $userid): \stdClass {
+ global $DB;
+ $record = new \stdClass();
+ $record->userid = $userid;
+ $record->method = "manual";
+ $record->password = "abc123";
+ $record->id = $DB->insert_record('auth_oidc_prevlogin', $record);
+ return $record;
+ }
+
+}
diff --git a/auth/oidc/ucp.php b/auth/oidc/ucp.php
new file mode 100644
index 00000000000..5d5d701e1fc
--- /dev/null
+++ b/auth/oidc/ucp.php
@@ -0,0 +1,110 @@
+.
+
+/**
+ * User control panel page.
+ *
+ * @package auth_oidc
+ * @author James McQuillan
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+require_once(__DIR__.'/../../config.php');
+require_once(__DIR__.'/auth.php');
+require_once(__DIR__.'/lib.php');
+
+require_login();
+
+$action = optional_param('action', null, PARAM_TEXT);
+
+$oidctoken = $DB->get_record('auth_oidc_token', ['userid' => $USER->id]);
+$oidcconnected = (!empty($oidctoken)) ? true : false;
+
+$oidcloginconnected = ($USER->auth === 'oidc') ? true : false;
+
+if (!is_enabled_auth('oidc')) {
+ throw new moodle_exception('erroroidcnotenabled', 'auth_oidc');
+}
+
+if (!empty($action)) {
+ if ($action === 'connectlogin' && $oidcloginconnected === false) {
+ // Use authorization request login flow to connect existing users.
+ auth_oidc_connectioncapability($USER->id, 'connect', true);
+ $auth = new \auth_oidc\loginflow\authcode;
+ $auth->set_httpclient(new \auth_oidc\httpclient());
+ $auth->initiateauthrequest();
+ } else if ($action === 'disconnectlogin' && $oidcloginconnected === true) {
+ if (is_enabled_auth('manual') === true) {
+ auth_oidc_connectioncapability($USER->id, 'disconnect', true);
+ $auth = new \auth_plugin_oidc;
+ $auth->set_httpclient(new \auth_oidc\httpclient());
+ $auth->disconnect();
+ }
+ } else {
+ throw new moodle_exception('errorucpinvalidaction', 'auth_oidc');
+ }
+} else {
+ $PAGE->set_url('/auth/oidc/ucp.php');
+ $usercontext = \context_user::instance($USER->id);
+ $PAGE->set_context(\context_system::instance());
+ $PAGE->set_pagelayout('standard');
+ $USER->editing = false;
+ $authconfig = get_config('auth_oidc');
+ $opname = (!empty($authconfig->opname)) ? $authconfig->opname : get_string('pluginname', 'auth_oidc');
+
+ $ucptitle = get_string('ucp_title', 'auth_oidc', $opname);
+ $PAGE->navbar->add($ucptitle, $PAGE->url);
+ $PAGE->set_title($ucptitle);
+
+ echo $OUTPUT->header();
+ echo \html_writer::tag('h2', $ucptitle);
+ echo get_string('ucp_general_intro', 'auth_oidc', $opname);
+ echo '
';
+
+ if (optional_param('o365accountconnected', null, PARAM_TEXT) == 'true') {
+ echo \html_writer::start_div('connectionstatus alert alert-error');
+ echo \html_writer::tag('h5', get_string('ucp_o365accountconnected', 'auth_oidc'));
+ echo \html_writer::end_div();
+ }
+
+ // Login status.
+ echo \html_writer::start_div('auth_oidc_ucp_indicator');
+ echo \html_writer::tag('h4', get_string('ucp_login_status', 'auth_oidc', $opname));
+ if ($oidcloginconnected === true) {
+ echo \html_writer::tag('h4', get_string('ucp_status_enabled', 'auth_oidc'), ['class' => 'notifysuccess']);
+ if (is_enabled_auth('manual') === true) {
+ if (auth_oidc_connectioncapability($USER->id, 'disconnect')) {
+ $connectlinkuri = new \moodle_url('/auth/oidc/ucp.php', ['action' => 'disconnectlogin']);
+ $strdisconnect = get_string('ucp_login_stop', 'auth_oidc', $opname);
+ $linkhtml = \html_writer::link($connectlinkuri, $strdisconnect);
+ echo \html_writer::tag('h5', $linkhtml);
+ echo \html_writer::span(get_string('ucp_login_stop_desc', 'auth_oidc', $opname));
+ }
+ }
+ } else {
+ echo \html_writer::tag('h4', get_string('ucp_status_disabled', 'auth_oidc'), ['class' => 'notifyproblem']);
+ if (auth_oidc_connectioncapability($USER->id, 'connect')) {
+ $connectlinkuri = new \moodle_url('/auth/oidc/ucp.php', ['action' => 'connectlogin']);
+ $linkhtml = \html_writer::link($connectlinkuri, get_string('ucp_login_start', 'auth_oidc', $opname));
+ echo \html_writer::tag('h5', $linkhtml);
+ echo \html_writer::span(get_string('ucp_login_start_desc', 'auth_oidc', $opname));
+ }
+ }
+ echo \html_writer::end_div();
+
+ echo $OUTPUT->footer();
+}
diff --git a/auth/oidc/version.php b/auth/oidc/version.php
new file mode 100644
index 00000000000..782cf2b9853
--- /dev/null
+++ b/auth/oidc/version.php
@@ -0,0 +1,32 @@
+.
+
+/**
+ * Plugin version information.
+ *
+ * @package auth_oidc
+ * @author James McQuillan
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2014 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$plugin->version = 2024100710;
+$plugin->requires = 2024100700;
+$plugin->release = '4.5.2';
+$plugin->component = 'auth_oidc';
+$plugin->maturity = MATURITY_STABLE;