class AppleOidcConfiguration extends OidcConfiguration {
    /**
     * Max expiration timeout for client secret (6 months in seconds)
     */
    private final static Duration MAX_TIMEOUT = Duration.ofSeconds(15777000);
    /**
     * Apple Auth Key
     */
    private ECPrivateKey privateKey;
    /**
     * Apple Auth Key ID
     */
    private String privateKeyID;
    /**
     * Apple Team ID
     */
    private String teamID;
    /**
     * Client secret cache store
     */
    private Store<String, String> store;
    /**
     * Client secret expiration timeout
     */
    private Duration timeout = MAX_TIMEOUT;

    /** {@inheritDoc} */
    @Override
    protected void internalInit(final boolean forceReinit) {<FILL_FUNCTION_BODY>}

    /**
     * {@inheritDoc}
     *
     * Generate client secret (JWT) and cache it until expiration timeout
     */
    @Override
    public String getSecret() {
        if (store != null) {
            var cache = store.get(getClientId());
            if (cache.isPresent()) {
                return cache.get();
            }
        }
        // https://developer.apple.com/documentation/sign_in_with_apple/generate_and_validate_tokens#3262048
        var claimsSet = new JWTClaimsSet.Builder()
            .issuer(getTeamID())
            .audience("https://appleid.apple.com")
            .subject(getClientId())
            .issueTime(Date.from(Instant.now()))
            .expirationTime(Date.from(Instant.now().plusSeconds(timeout.toSeconds())))
            .build();
        var signedJWT = new SignedJWT(
            new JWSHeader.Builder(JWSAlgorithm.ES256).keyID(privateKeyID).build(),
            claimsSet);
        JWSSigner signer;
        try {
            signer = new ECDSASigner(privateKey);
            signedJWT.sign(signer);
        } catch (JOSEException e) {
            throw new OidcException(e);
        }
        var secret = signedJWT.serialize();
        if (store != null) {
            store.set(getClientId(), secret);
        }
        return secret;
    }
}

        // checks
        CommonHelper.assertNotBlank("privateKeyID", privateKeyID);
        CommonHelper.assertNotNull("privateKey", privateKey);
        CommonHelper.assertNotBlank("teamID", teamID);
        if (timeout.compareTo(MAX_TIMEOUT) > 0) {
            throw new IllegalArgumentException(String.format("timeout must not be greater then %d seconds", MAX_TIMEOUT.toSeconds()));
        }
        if (store == null) {
            store = new GuavaStore<>(1000, (int) timeout.toSeconds(), TimeUnit.SECONDS);
        }
        val providerMetadata =
            new OIDCProviderMetadata(
                new Issuer("https://appleid.apple.com"),
                Collections.singletonList(SubjectType.PAIRWISE),
                // https://developer.apple.com/documentation/signinwithapplerestapi/fetch_apple_s_public_key_for_verifying_token_signature
                URI.create("https://appleid.apple.com/auth/keys"));
// https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms
        providerMetadata.setAuthorizationEndpointURI(URI.create("https://appleid.apple.com/auth/authorize"));
        // https://developer.apple.com/documentation/sign_in_with_apple/generate_and_validate_tokens
        providerMetadata.setTokenEndpointURI(URI.create("https://appleid.apple.com/auth/token"));
        providerMetadata.setIDTokenJWSAlgs(Collections.singletonList(JWSAlgorithm.RS256));
        this.opMetadataResolver = new StaticOidcOpMetadataResolver(this, providerMetadata);
        setClientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST);

        super.internalInit(forceReinit);
    
<methods>public non-sealed void <init>() ,public void addCustomParam(java.lang.String, java.lang.String) ,public void configureHttpRequest(com.nimbusds.oauth2.sdk.http.HTTPRequest) ,public java.lang.String findLogoutUrl() ,public com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod findPkceMethod() ,public com.nimbusds.jose.util.ResourceRetriever findResourceRetriever() ,public java.lang.String getCustomParam(java.lang.String) ,public java.lang.String getResponseType() ,public int getTokenExpirationAdvance() ,public void setClientAuthenticationMethodAsString(java.lang.String) ,public void setCodeVerifierGenerator(org.pac4j.core.util.generator.ValueGenerator) ,public void setCustomParams(Map<java.lang.String,java.lang.String>) ,public void setDiscoveryURIIfUndefined(java.lang.String) ,public void setPreferredJwsAlgorithmAsString(java.lang.String) ,public void setResponseType(java.lang.String) ,public void setStateGenerator(org.pac4j.core.util.generator.ValueGenerator) ,public void setSupportedClientAuthenticationMethods(Set<com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod>) ,public void setValueRetriever(org.pac4j.oidc.util.ValueRetriever) <variables>public static final List<com.nimbusds.oauth2.sdk.ResponseType> AUTHORIZATION_CODE_FLOWS,public static final java.lang.String CLIENT_ID,public static final java.lang.String CODE_CHALLENGE,public static final java.lang.String CODE_CHALLENGE_METHOD,public static final java.lang.String CUSTOM_PARAMS,public static final int DEFAULT_MAX_CLOCK_SKEW,public static final int DEFAULT_TOKEN_EXPIRATION_ADVANCE,public static final List<com.nimbusds.oauth2.sdk.ResponseType> HYBRID_CODE_FLOWS,public static final List<com.nimbusds.oauth2.sdk.ResponseType> IMPLICIT_FLOWS,public static final java.lang.String MAX_AGE,public static final java.lang.String NONCE,public static final java.lang.String PROMPT,public static final java.lang.String REDIRECT_URI,public static final java.lang.String RESPONSE_MODE,public static final java.lang.String RESPONSE_TYPE,public static final java.lang.String SCOPE,public static final java.lang.String STATE,private boolean allowUnsignedIdTokens,private boolean callUserInfoEndpoint,private com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod clientAuthenticationMethod,private java.lang.String clientId,private org.pac4j.core.util.generator.ValueGenerator codeVerifierGenerator,private int connectTimeout,private Map<java.lang.String,java.lang.String> customParams,private boolean disablePkce,private java.lang.String discoveryURI,private boolean expireSessionWithToken,private javax.net.ssl.HostnameVerifier hostnameVerifier,private boolean includeAccessTokenClaimsInProfile,private java.lang.String logoutUrl,private Map<java.lang.String,java.lang.String> mappedClaims,private java.lang.Integer maxAge,private int maxClockSkew,protected org.pac4j.oidc.metadata.OidcOpMetadataResolver opMetadataResolver,private com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod pkceMethod,private com.nimbusds.jose.JWSAlgorithm preferredJwsAlgorithm,private org.pac4j.oidc.config.PrivateKeyJWTClientAuthnMethodConfig privateKeyJWTClientAuthnMethodConfig,private int readTimeout,private com.nimbusds.jose.util.ResourceRetriever resourceRetriever,private java.lang.String responseMode,private com.nimbusds.oauth2.sdk.ResponseType responseType,private java.lang.String scope,private java.lang.String secret,private javax.net.ssl.SSLSocketFactory sslSocketFactory,private org.pac4j.core.util.generator.ValueGenerator stateGenerator,private Set<com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod> supportedClientAuthenticationMethods,private int tokenExpirationAdvance,private boolean useNonce,private org.pac4j.oidc.util.ValueRetriever valueRetriever,private boolean withState